깊은바다거북
개발 공부 기록
깊은바다거북
전체 방문자
오늘
어제
  • 분류 전체보기 (219)
    • JAVA (9)
    • JavaScript (15)
    • 스파르타코딩클럽 (11)
      • [내일배움단] 웹개발 종합반 개발일지 (5)
      • [내일배움캠프] 프로젝트와 트러블 슈팅 (6)
    • SQL | NoSQL (4)
    • CS 등등 (0)
    • TIL | WIL (173)
    • 기타 에러 해결 (3)
    • 내 살 길 궁리 (4)

인기 글

최근 글

최근 댓글

태그

  • DFS(깊이우선탐색)
  • TIT (Today I Troubleshot)
  • Preorder Traversal(전위 순회)
  • Linked List
  • 코딩테스트 연습문제
  • 01. 미니 프로젝트
  • 자잘한 에러 해결
  • 프로그래머스
  • 트러블 슈팅 Troubleshooting
  • leetcode-cli
  • TypeScript
  • Inorder Traversal(중위 순회)
  • Til
  • Trie
  • 자바스크립트 기초 문법
  • 재귀 함수
  • BFS(너비우선탐색)
  • tree
  • 팀 프로젝트
  • 자료 구조
  • 점화식(Recurrence Relation)
  • 시간 복잡도
  • 최소 힙(Min Heap)
  • 혼자 공부하는 자바스크립트
  • POST / GET 요청
  • Binary Tree(이진 트리)
  • 최대 힙(Max Heap)
  • Backtracking(백트래킹)
  • BST(이진 탐색 트리)
  • Leetcode
hELLO · Designed By 정상우.
깊은바다거북

개발 공부 기록

TIL | WIL

8/30 (수) 깊이 우선 탐색(DFS) 예제 코드TIL

2023. 8. 30. 23:58

공부한 것

  • LeetCode #110. Balanced Binary Tree
    LeetCode - The World's Leading Online Programming Learning Platform
    Level up your coding skills and quickly land a job. This is the best place to expand your knowledge and get prepared for your next interview.
    https://leetcode.com/problems/balanced-binary-tree/description/

    이상한 테스트 케이스 하나가 있는 것으로 결론 내리고 마무리 지었다.

배운 것

  • 깊이 우선 탐색(DFS)에 해당하는 예제와 생각 과정은 다음과 같다:
    • 로직:

      1) 현재 노드가 null이면 0을 반환하고,

      2) 현재 노드의 두 '자식 노드'에 대한 재귀호출로 현재 잎 노드부터 자식 노드까지의 판단을 불러온다.

      2-1) 결과가 어차피 -1이었으면 바로 -1을 반환해주도록 한다. '현재 노드'에 대한 판단을 반환한다:

      3-1) 이전 '자식 노드' 재귀호출에서는 딱 '자식 자기 자신'까지만 포함한 상태로 깊이 판단을 하였을 것이므로, '형제 노드'와의 깊이 비교는 이루어지지 않았을 것이다. 따라서 '현재(부모) 노드'의 두 자식 노드의 깊이를 비교해주고, 2 이상 차이나면 - 1을 반환한다.

      3-2) 그렇지 않으면(두 자식의 깊이가 1만 차이나거나 같다면) 더 깊은 자식을 골라 1을 더한 현재까지의 깊이를 반환한다.

    • 위의 로직을 얻기 위한 생각의 흐름은 다음과 같다:

      (1)두 자식 트리의 깊이를 비교해야 한다 -> 두 자식 트리의 깊이를 각각 불러온다. (2)그렇게 불러온 두 깊이가 2 이상 차이나면 '균형 아님'으로 판단해야 한다 -> 두 깊이가 2 이상 차이나면 -1을 반환하도록 한다.

      (1)+(2)가 '현재 노드'에 대한 판단 로직이고, (1)을 재귀적으로 구할 수 있을 것 같다. 그렇다면 두 깊이가 2 이상 차이날 때 '균형 아님'으로 판단하는 것 뿐만 아니라 반환 결과값이 '현재 노드 이하 트리의 깊이'가 될 수 있도록 숫자값이 되어야 하고, 또 탈출 조건이 필요해진다:

      (3)두 자식 트리의 깊이가 2 이상 차이나면 '균형 아님'으로 -1을 반환하도록 만들고, 반대로 1 이하로 차이나면 '균형임'으로 현재 노드까지의 깊이값을 반환해주면 되겠다 -> 두 자식 트리 깊이가 같을 때 아무 자식의 깊이에 1을 더한 값을, 두 자식 트리 깊이가 1 차이날 때 더 깊은 자식의 깊이에 1을 더한 값을 반환한다. 즉, 두 자식 트리 중 더 깊은 자식의 깊이에 1을 더한 값이 '현재 노드' 레벨까지 추가한 현재 깊이가 된다.

      (4)탈출 조건은 처음에 깊이 숫자값이 시작되는 지점이기도 해야 한다. 즉, 탈출 반환값이 숫자값이 되어야 한다. 나 자신 노드를 레벨 하나로 셈하므로, 반대로 만약 나 자신 노드가 '없다면' 더해지는 레벨이 0인 것이다. 그렇다면 현재 노드가 null일 때 0을 반환하든지 현재 노드가 잎 노드일 때 1을 반환하든지 하여 탈출 조건을 짜면 되겠다.

      (5)엇 그런데 최종적으로 반환해야 하는 형태는 true/false의 불리언이다. 지금 만드는 재귀함수는 숫자값을 반환해야 하므로, 결국 본체 solution 함수 외에 보조 재귀함수를 만들어야 한다는 결론이 나온다.

    • 위의 로직을 구현한 코드:
      function solution6(root: TreeNode | null): boolean {
      
      	function subTreeDepth(node: TreeNode | null): number {
      		// 0. 탈출 조건: 현재 노드가 잎 노드이면 1을 반환하도록 한다.
      		// if (!node.left && !node.right && node) return 1;
      		if (!node) return 0;
      	
      		// 1. 두 자식 트리의 깊이를 각각 불러온다. 
      		const leftDepth = subTreeDepth(node.left); // node.left가 null일 때의 대처가 없다.
      		const rightDepth = subTreeDepth(node.right);
      		// 1-1. 
      		if (leftDepth === -1 || rightDepth === -1) return -1;
      
      		// 2. 그렇게 불러온 두 깊이가 2 이상 차이나면 '균형 아님'을, 즉 -1을 반환하도록 한다. 
      		if (Math.abs(leftDepth - rightDepth) > 1) return -1;
      		// => 둘의 결과값이 -1인 경우에는 '차' 계산값이 이상해진다. 결국 -1의 경우를 따로 취급해줘야 한다. -> 1.1 조건 추가. 
      		// 3. 반대로 깊이가 1 이하로 차이나면 '균형임'을, 즉 두 자식 트리 중 더 깊은 자식의 깊이에 '현재 노드'의 레벨까지 +1을 더한 값을 반환한다. 
      		return Math.max(leftDepth, rightDepth) + 1;
      	}
      
      	return subTreeDepth(root) !== -1;
      }


Uploaded by N2T

    'TIL | WIL' 카테고리의 다른 글
    • 9/1 (금) 트리 문제 기초 접근법을 3가지로 정리하다 TIL
    • 8/31 (목) 트리 순회 3형제는 깊이 우선 탐색(DFS)의 일종이다 TIL
    • 8/29 (화) Tree의 깊이 탐색하기 TIL
    • 8/28 (월) 너비 우선 탐색(BFS)과 새로운 메소드 TIL
    깊은바다거북
    깊은바다거북

    티스토리툴바