Leetcode 문제 - 데이터 구조의 트리
차례로 돌아가다
한 그루의 나무는 빈 나무이거나 두 개의 바늘이 있는데, 바늘마다 한 그루의 나무를 가리킨다.나무는 일종의 귀속 구조로 많은 나무의 문제는 귀속으로 처리할 수 있다.
1. 나무의 높이
104. Maximum Depth of Binary Tree (Easy) public int maxDepth(TreeNode root) {
if (root == null) return 0; return Math.max(maxDepth(root.left), maxDepth(root.right)) + 1; }
2. 밸런스 트리
110. Balanced Binary Tree (Easy) 3
/ \
9 20
/ \
15 7
평형수 좌우자 나무의 높이 차이는 모두 1보다 작다private boolean result = true;
public boolean isBalanced(TreeNode root) { maxDepth(root); return result; } public int maxDepth(TreeNode root) { if (root == null) return 0; int l = maxDepth(root.left); int r = maxDepth(root.right); if (Math.abs(l - r) > 1) result = false; return 1 + Math.max(l, r); }
3. 두 노드의 최장 경로
543. Diameter of Binary Tree (Easy) Input:
1
/ \
2 3
/ \
4 5
Return 3, which is the length of the path [4,2,1,3] or [5,2,1,3].
private int max = 0;
public int diameterOfBinaryTree(TreeNode root) { depth(root); return max; } private int depth(TreeNode root) { if (root == null) return 0; int leftDepth = depth(root.left); int rightDepth = depth(root.right); max = Math.max(max, leftDepth + rightDepth); return Math.max(leftDepth, rightDepth) + 1; }
4. 나무 뒤집기
226. Invert Binary Tree (Easy) public TreeNode invertTree(TreeNode root) {
if (root == null) return null; TreeNode left = root.left; // left , root.left = invertTree(root.right); root.right = invertTree(left); return root; }
5. 나무 두 그루를 합친다
617. Merge Two Binary Trees (Easy) Input:
Tree 1 Tree 2
1 2
/ \ / \
3 2 1 3
/ \ \
5 4 7
Output:
3
/ \
4 5
/ \ \
5 4 7
public TreeNode mergeTrees(TreeNode t1, TreeNode t2) {
if (t1 == null && t2 == null) return null; if (t1 == null) return t2; if (t2 == null) return t1; TreeNode root = new TreeNode(t1.val + t2.val); root.left = mergeTrees(t1.left, t2.left); root.right = mergeTrees(t1.right, t2.right); return root; }
6. 경로와 같은 수인지 판단
Leetcdoe : 112. Path Sum (Easy) Given the below binary tree and sum = 22,
5
/ \
4 8
/ / \
11 13 4
/ \ \
7 2 1
return true, as there exist a root-to-leaf path 5->4->11->2 which sum is 22.
루트에서 leaf까지의 모든 노드의 합을 경로와 정의합니다.public boolean hasPathSum(TreeNode root, int sum) {
if (root == null) return false; if (root.left == null && root.right == null && root.val == sum) return true; return hasPathSum(root.left, sum - root.val) || hasPathSum(root.right, sum - root.val); }
7. 통계 경로와 같은 경로 수
437. Path Sum III (Easy) root = [10,5,-3,3,2,null,11,3,-2,null,1], sum = 8
10
/ \
5 -3
/ \ \
3 2 11
/ \ \
3 -2 1
Return 3. The paths that sum to 8 are:
1. 5 -> 3
2. 5 -> 2 -> 1
3. -3 -> 11
경로가 루트로 시작하거나 leaf로 끝나는 것은 아니지만 연속해야 합니다.public int pathSum(TreeNode root, int sum) {
if (root == null) return 0; int ret = pathSumStartWithRoot(root, sum) + pathSum(root.left, sum) + pathSum(root.right, sum); return ret; } private int pathSumStartWithRoot(TreeNode root, int sum) { if (root == null) return 0; int ret = 0; if (root.val == sum) ret++; ret += pathSumStartWithRoot(root.left, sum - root.val) + pathSumStartWithRoot(root.right, sum - root.val); return ret; }
8. 자목
572. Subtree of Another Tree (Easy) Given tree s:
3
/ \
4 5
/ \
1 2
Given tree t:
4
/ \
1 2
Return true, because t has the same structure and node values with a subtree of s.
Given tree s:
3
/ \
4 5
/ \
1 2
/
0
Given tree t:
4
/ \
1 2
Return false.
public boolean isSubtree(TreeNode s, TreeNode t) {
if (s == null) return false; return isSubtreeWithRoot(s, t) || isSubtree(s.left, t) || isSubtree(s.right, t); } private boolean isSubtreeWithRoot(TreeNode s, TreeNode t) { if (t == null && s == null) return true; if (t == null || s == null) return false; if (t.val != s.val) return false; return isSubtreeWithRoot(s.left, t.left) && isSubtreeWithRoot(s.right, t.right); }
9. 나무의 대칭
101. Symmetric Tree (Easy) 1
/ \
2 2
/ \ / \
3 4 4 3
public boolean isSymmetric(TreeNode root) {
if (root == null) return true; return isSymmetric(root.left, root.right); } private boolean isSymmetric(TreeNode t1, TreeNode t2) { if (t1 == null && t2 == null) return true; if (t1 == null || t2 == null) return false; if (t1.val != t2.val) return false; return isSymmetric(t1.left, t2.right) && isSymmetric(t1.right, t2.left); }
10. 최소 경로
111. Minimum Depth of Binary Tree (Easy)
나무의 뿌리 노드에서 잎 노드까지의 최소 경로 길이public int minDepth(TreeNode root) {
if (root == null) return 0; int left = minDepth(root.left); int right = minDepth(root.right); if (left == 0 || right == 0) return left + right + 1; return Math.min(left, right) + 1; }
11. 왼쪽 잎 노드의 합을 통계한다
404. Sum of Left Leaves (Easy) 3
/ \
9 20
/ \
15 7
There are two left leaves in the binary tree, with values 9 and 15 respectively. Return 24.
public int sumOfLeftLeaves(TreeNode root) {
if (root == null) return 0; if (isLeaf(root.left)) return root.left.val + sumOfLeftLeaves(root.right); return sumOfLeftLeaves(root.left) + sumOfLeftLeaves(root.right); } private boolean isLeaf(TreeNode node){ if (node == null) return false; return node.left == null && node.right == null; }
12. 동일한 노드 값의 최대 경로 길이
687. Longest Univalue Path (Easy) 1
/ \
4 5
/ \ \
4 4 5
Output : 2
private int path = 0;
public int longestUnivaluePath(TreeNode root) { dfs(root); return path; } private int dfs(TreeNode root){ if (root == null) return 0; int left = dfs(root.left); int right = dfs(root.right); int leftPath = root.left != null && root.left.val == root.val ? left + 1 : 0; int rightPath = root.right != null && root.right.val == root.val ? right + 1 : 0; path = Math.max(path, leftPath + rightPath); return Math.max(leftPath, rightPath); }
13. 간격을 두고 두루 다니다
337. House Robber III (Medium) 3
/ \
2 3
\ \
3 1
Maximum amount of money the thief can rob = 3 + 3 + 1 = 7.
public int rob(TreeNode root) {
if (root == null) return 0; int val1 = root.val; if (root.left != null) val1 += rob(root.left.left) + rob(root.left.right); if (root.right != null) val1 += rob(root.right.left) + rob(root.right.right); int val2 = rob(root.left) + rob(root.right); return Math.max(val1, val2); }
14. 두 갈래 나무 중 두 번째로 작은 노드를 찾아낸다
671. Second Minimum Node In a Binary Tree (Easy) Input:
2
/ \
2 5
/ \
5 7
Output: 5
하나의 노드는 0개 또는 2개의 자 노드를 가지고 있으며, 만약 자 노드가 있다면, 뿌리 노드는 가장 작은 노드이다.public int findSecondMinimumValue(TreeNode root) {
if (root == null) return -1; if (root.left == null && root.right == null) return -1; int leftVal = root.left.val; int rightVal = root.right.val; if (leftVal == root.val) leftVal = findSecondMinimumValue(root.left); if (rightVal == root.val) rightVal = findSecondMinimumValue(root.right); if (leftVal != -1 && rightVal != -1) return Math.min(leftVal, rightVal); if (leftVal != -1) return leftVal; return rightVal; }
층층이 두루 다니다
BFS를 사용하여 계층 이동합니다.두 개의 대기열을 사용하여 현재 층의 노드와 다음 층의 노드를 각각 저장할 필요가 없다. 왜냐하면 한 층의 노드를 훑어보기 시작할 때 현재 대기열의 노드 수는 현재 층의 노드 수이기 때문이다. 이렇게 많은 노드를 훑어보기만 하면 이번에 훑어보는 노드가 모두 현재 층의 노드임을 보장할 수 있기 때문이다.
1. 나무 한 그루의 층별 노드 평균수
637. Average of Levels in Binary Tree (Easy) public List<Double> averageOfLevels(TreeNode root) {
List<Double> ret = new ArrayList<>(); if (root == null) return ret; Queue<TreeNode> queue = new LinkedList<>(); queue.add(root); while (!queue.isEmpty()) { int cnt = queue.size(); double sum = 0; for (int i = 0; i < cnt; i++) { TreeNode node = queue.poll(); sum += node.val; if (node.left != null) queue.add(node.left); if (node.right != null) queue.add(node.right); } ret.add(sum / cnt); } return ret; }
2. 왼쪽 아래 모서리의 노드 얻기
513. Find Bottom Left Tree Value (Easy) Input:
1
/ \
2 3
/ / \
4 5 6
/
7
Output:
7
public int findBottomLeftValue(TreeNode root) {
Queue<TreeNode> queue = new LinkedList<>(); queue.add(root); while (!queue.isEmpty()) { root = queue.poll(); if (root.right != null) queue.add(root.right); if (root.left != null) queue.add(root.left); } return root.val; }
앞뒤가 두루 다니다 1
/ \
2 3
/ \ \
4 5 6
public int maxDepth(TreeNode root) {
if (root == null) return 0; return Math.max(maxDepth(root.left), maxDepth(root.right)) + 1; }
3
/ \
9 20
/ \
15 7
private boolean result = true;
public boolean isBalanced(TreeNode root) { maxDepth(root); return result; } public int maxDepth(TreeNode root) { if (root == null) return 0; int l = maxDepth(root.left); int r = maxDepth(root.right); if (Math.abs(l - r) > 1) result = false; return 1 + Math.max(l, r); }
Input:
1
/ \
2 3
/ \
4 5
Return 3, which is the length of the path [4,2,1,3] or [5,2,1,3].
private int max = 0;
public int diameterOfBinaryTree(TreeNode root) { depth(root); return max; } private int depth(TreeNode root) { if (root == null) return 0; int leftDepth = depth(root.left); int rightDepth = depth(root.right); max = Math.max(max, leftDepth + rightDepth); return Math.max(leftDepth, rightDepth) + 1; }
public TreeNode invertTree(TreeNode root) {
if (root == null) return null; TreeNode left = root.left; // left , root.left = invertTree(root.right); root.right = invertTree(left); return root; }
Input:
Tree 1 Tree 2
1 2
/ \ / \
3 2 1 3
/ \ \
5 4 7
Output:
3
/ \
4 5
/ \ \
5 4 7
public TreeNode mergeTrees(TreeNode t1, TreeNode t2) {
if (t1 == null && t2 == null) return null; if (t1 == null) return t2; if (t2 == null) return t1; TreeNode root = new TreeNode(t1.val + t2.val); root.left = mergeTrees(t1.left, t2.left); root.right = mergeTrees(t1.right, t2.right); return root; }
Given the below binary tree and sum = 22,
5
/ \
4 8
/ / \
11 13 4
/ \ \
7 2 1
return true, as there exist a root-to-leaf path 5->4->11->2 which sum is 22.
public boolean hasPathSum(TreeNode root, int sum) {
if (root == null) return false; if (root.left == null && root.right == null && root.val == sum) return true; return hasPathSum(root.left, sum - root.val) || hasPathSum(root.right, sum - root.val); }
root = [10,5,-3,3,2,null,11,3,-2,null,1], sum = 8
10
/ \
5 -3
/ \ \
3 2 11
/ \ \
3 -2 1
Return 3. The paths that sum to 8 are:
1. 5 -> 3
2. 5 -> 2 -> 1
3. -3 -> 11
public int pathSum(TreeNode root, int sum) {
if (root == null) return 0; int ret = pathSumStartWithRoot(root, sum) + pathSum(root.left, sum) + pathSum(root.right, sum); return ret; } private int pathSumStartWithRoot(TreeNode root, int sum) { if (root == null) return 0; int ret = 0; if (root.val == sum) ret++; ret += pathSumStartWithRoot(root.left, sum - root.val) + pathSumStartWithRoot(root.right, sum - root.val); return ret; }
Given tree s:
3
/ \
4 5
/ \
1 2
Given tree t:
4
/ \
1 2
Return true, because t has the same structure and node values with a subtree of s.
Given tree s:
3
/ \
4 5
/ \
1 2
/
0
Given tree t:
4
/ \
1 2
Return false.
public boolean isSubtree(TreeNode s, TreeNode t) {
if (s == null) return false; return isSubtreeWithRoot(s, t) || isSubtree(s.left, t) || isSubtree(s.right, t); } private boolean isSubtreeWithRoot(TreeNode s, TreeNode t) { if (t == null && s == null) return true; if (t == null || s == null) return false; if (t.val != s.val) return false; return isSubtreeWithRoot(s.left, t.left) && isSubtreeWithRoot(s.right, t.right); }
1
/ \
2 2
/ \ / \
3 4 4 3
public boolean isSymmetric(TreeNode root) {
if (root == null) return true; return isSymmetric(root.left, root.right); } private boolean isSymmetric(TreeNode t1, TreeNode t2) { if (t1 == null && t2 == null) return true; if (t1 == null || t2 == null) return false; if (t1.val != t2.val) return false; return isSymmetric(t1.left, t2.right) && isSymmetric(t1.right, t2.left); }
public int minDepth(TreeNode root) {
if (root == null) return 0; int left = minDepth(root.left); int right = minDepth(root.right); if (left == 0 || right == 0) return left + right + 1; return Math.min(left, right) + 1; }
3
/ \
9 20
/ \
15 7
There are two left leaves in the binary tree, with values 9 and 15 respectively. Return 24.
public int sumOfLeftLeaves(TreeNode root) {
if (root == null) return 0; if (isLeaf(root.left)) return root.left.val + sumOfLeftLeaves(root.right); return sumOfLeftLeaves(root.left) + sumOfLeftLeaves(root.right); } private boolean isLeaf(TreeNode node){ if (node == null) return false; return node.left == null && node.right == null; }
1
/ \
4 5
/ \ \
4 4 5
Output : 2
private int path = 0;
public int longestUnivaluePath(TreeNode root) { dfs(root); return path; } private int dfs(TreeNode root){ if (root == null) return 0; int left = dfs(root.left); int right = dfs(root.right); int leftPath = root.left != null && root.left.val == root.val ? left + 1 : 0; int rightPath = root.right != null && root.right.val == root.val ? right + 1 : 0; path = Math.max(path, leftPath + rightPath); return Math.max(leftPath, rightPath); }
3
/ \
2 3
\ \
3 1
Maximum amount of money the thief can rob = 3 + 3 + 1 = 7.
public int rob(TreeNode root) {
if (root == null) return 0; int val1 = root.val; if (root.left != null) val1 += rob(root.left.left) + rob(root.left.right); if (root.right != null) val1 += rob(root.right.left) + rob(root.right.right); int val2 = rob(root.left) + rob(root.right); return Math.max(val1, val2); }
Input:
2
/ \
2 5
/ \
5 7
Output: 5
public int findSecondMinimumValue(TreeNode root) {
if (root == null) return -1; if (root.left == null && root.right == null) return -1; int leftVal = root.left.val; int rightVal = root.right.val; if (leftVal == root.val) leftVal = findSecondMinimumValue(root.left); if (rightVal == root.val) rightVal = findSecondMinimumValue(root.right); if (leftVal != -1 && rightVal != -1) return Math.min(leftVal, rightVal); if (leftVal != -1) return leftVal; return rightVal; }
BFS를 사용하여 계층 이동합니다.두 개의 대기열을 사용하여 현재 층의 노드와 다음 층의 노드를 각각 저장할 필요가 없다. 왜냐하면 한 층의 노드를 훑어보기 시작할 때 현재 대기열의 노드 수는 현재 층의 노드 수이기 때문이다. 이렇게 많은 노드를 훑어보기만 하면 이번에 훑어보는 노드가 모두 현재 층의 노드임을 보장할 수 있기 때문이다.
1. 나무 한 그루의 층별 노드 평균수
637. Average of Levels in Binary Tree (Easy)
public List<Double> averageOfLevels(TreeNode root) {
List<Double> ret = new ArrayList<>(); if (root == null) return ret; Queue<TreeNode> queue = new LinkedList<>(); queue.add(root); while (!queue.isEmpty()) { int cnt = queue.size(); double sum = 0; for (int i = 0; i < cnt; i++) { TreeNode node = queue.poll(); sum += node.val; if (node.left != null) queue.add(node.left); if (node.right != null) queue.add(node.right); } ret.add(sum / cnt); } return ret; }
2. 왼쪽 아래 모서리의 노드 얻기
513. Find Bottom Left Tree Value (Easy)
Input:
1
/ \
2 3
/ / \
4 5 6
/
7
Output:
7
public int findBottomLeftValue(TreeNode root) {
Queue<TreeNode> queue = new LinkedList<>(); queue.add(root); while (!queue.isEmpty()) { root = queue.poll(); if (root.right != null) queue.add(root.right); if (root.left != null) queue.add(root.left); } return root.val; }
앞뒤가 두루 다니다 1
/ \
2 3
/ \ \
4 5 6
1
/ \
2 3
/ \ \
4 5 6
차원 반복은 BFS를 사용하여 이루어진다. 그것이 바로 BFS의 층층이 반복되는 특성이다.DFS를 사용하여 앞, 중간, 뒤의 순서를 반복합니다.
앞 순서, 중간 순서, 뒤 순서는 노드에 접근하는 순서에 따라 조금씩 다를 뿐, 다른 것은 모두 같다.
① 앞 순서
void dfs(TreeNode root) {
visit(root);
dfs(root.left);
dfs(root.right);
}
② 중서
void dfs(TreeNode root) {
dfs(root.left);
visit(root);
dfs(root.right);
}
③ 후순
void dfs(TreeNode root) {
dfs(root.left);
dfs(root.right);
visit(root);
}
1. 비귀속 실현 두 갈래 나무의 앞차례 반복
144. Binary Tree Preorder Traversal (Medium)
public List<Integer> preorderTraversal(TreeNode root) {
List<Integer> ret = new ArrayList<>(); Stack<TreeNode> stack = new Stack<>(); stack.push(root); while (!stack.isEmpty()) { TreeNode node = stack.pop(); if (node == null) continue; ret.add(node.val); stack.push(node.right); // , stack.push(node.left); } return ret; }
2. 비귀속 실현 두 갈래 나무의 뒷차례 반복
145. Binary Tree Postorder Traversal (Medium)
앞 순서는 루트->left->right, 뒤 순서는 left->right->root입니다.앞의 순서를 루트->right->left로 수정할 수 있습니다. 그러면 이 순서는 뒤의 순서와 정반대입니다.
public List<Integer> postorderTraversal(TreeNode root) {
List<Integer> ret = new ArrayList<>(); Stack<TreeNode> stack = new Stack<>(); stack.push(root); while (!stack.isEmpty()) { TreeNode node = stack.pop(); if (node == null) continue; ret.add(node.val); stack.push(node.left); stack.push(node.right); } Collections.reverse(ret); return ret; }
3. 비귀속 실현 두 갈래 나무의 중차 반복
94. Binary Tree Inorder Traversal (Medium)
public List<Integer> inorderTraversal(TreeNode root) {
List<Integer> ret = new ArrayList<>(); if (root == null) return ret; Stack<TreeNode> stack = new Stack<>(); TreeNode cur = root; while (cur != null || !stack.isEmpty()) { while (cur != null) { stack.push(cur); cur = cur.left; } TreeNode node = stack.pop(); ret.add(node.val); cur = node.right; } return ret; }
BST
두 갈래 찾기 트리(BST): 루트 노드는 왼쪽 트리의 모든 노드보다 크고 오른쪽 트리의 모든 노드보다 작습니다.
두 갈래 찾기 트리의 순서가 질서정연하다.
1. 두 갈래로 나무 찾기
669. Trim a Binary Search Tree (Easy) Input:
3
/ \
0 4
\
2
/
1
L = 1
R = 3
Output:
3
/
2
/
1
제목 설명: L~R 사이의 노드만 보존public TreeNode trimBST(TreeNode root, int L, int R) { if (root == null) return null; if (root.val > R) return trimBST(root.left, L, R); if (root.val < L) return trimBST(root.right, L, R); root.left = trimBST(root.left, L, R); root.right = trimBST(root.right, L, R); return root; }
2. 두 갈래 찾기 나무의 k번째 원소 찾기
230. Kth Smallest Element in a BST (Medium)
중간 순서 반복 해법:private int cnt = 0;
private int val; public int kthSmallest(TreeNode root, int k) { inOrder(root, k); return val; } private void inOrder(TreeNode node, int k) { if (node == null) return; inOrder(node.left, k); cnt++; if (cnt == k) { val = node.val; return; } inOrder(node.right, k); }
반복 해법:public int kthSmallest(TreeNode root, int k) {
int leftCnt = count(root.left); if (leftCnt == k - 1) return root.val; if (leftCnt > k - 1) return kthSmallest(root.left, k); return kthSmallest(root.right, k - leftCnt - 1); } private int count(TreeNode node) { if (node == null) return 0; return 1 + count(node.left) + count(node.right); }
3. 두 갈래 찾기 트리의 각 노드의 값에 그것보다 큰 노드의 값을 더한다
Convert BST to Greater Tree (Easy) Input: The root of a Binary Search Tree like this:
5
/ \
2 13
Output: The root of a Greater Tree like this:
18
/ \
20 13
먼저 오른쪽 나무를 두루 훑어보다.private int sum = 0;
public TreeNode convertBST(TreeNode root) { traver(root); return root; } private void traver(TreeNode node) { if (node == null) return; traver(node.right); sum += node.val; node.val = sum; traver(node.left); }
4. 두 갈래로 나무의 최근 조상 찾기
235. Lowest Common Ancestor of a Binary Search Tree (Easy) _______6______
/ \
___2__ ___8__
/ \ / \
0 4 7 9
/ \
3 5
For example, the lowest common ancestor (LCA) of nodes 2 and 8 is 6. Another example is LCA of nodes 2 and 4 is 2, since a node can be a descendant of itself according to the LCA definition.
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
if (root.val > p.val && root.val > q.val) return lowestCommonAncestor(root.left, p, q); if (root.val < p.val && root.val < q.val) return lowestCommonAncestor(root.right, p, q); return root; }
5. 두 갈래 나무의 최근 조상
236. Lowest Common Ancestor of a Binary Tree (Medium) _______3______
/ \
___5__ ___1__
/ \ / \
6 2 0 8
/ \
7 4
For example, the lowest common ancestor (LCA) of nodes 5 and 1 is 3. Another example is LCA of nodes 5 and 4 is 5, since a node can be a descendant of itself according to the LCA definition.
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
if (root == null || root == p || root == q) return root; TreeNode left = lowestCommonAncestor(root.left, p, q); TreeNode right = lowestCommonAncestor(root.right, p, q); return left == null ? right : right == null ? left : root; }
6. 질서수 그룹에서 두 갈래로 트리 찾기
108. Convert Sorted Array to Binary Search Tree (Easy) public TreeNode sortedArrayToBST(int[] nums) {
return toBST(nums, 0, nums.length - 1); } private TreeNode toBST(int[] nums, int sIdx, int eIdx){ if (sIdx > eIdx) return null; int mIdx = (sIdx + eIdx) / 2; TreeNode root = new TreeNode(nums[mIdx]); root.left = toBST(nums, sIdx, mIdx - 1); root.right = toBST(nums, mIdx + 1, eIdx); return root; }
7. 질서정연한 체인 테이블 구조에 따라 균형 잡힌 두 갈래 찾기 트리
109. Convert Sorted List to Binary Search Tree (Medium) Given the sorted linked list: [-10,-3,0,5,9],
One possible answer is: [0,-3,9,-10,null,5], which represents the following height balanced BST:
0
/ \
-3 9
/ /
-10 5
public TreeNode sortedListToBST(ListNode head) {
if (head == null) return null; if (head.next == null) return new TreeNode(head.val); ListNode preMid = preMid(head); ListNode mid = preMid.next; preMid.next = null; // TreeNode t = new TreeNode(mid.val); t.left = sortedListToBST(head); t.right = sortedListToBST(mid.next); return t; } private ListNode preMid(ListNode head) { ListNode slow = head, fast = head.next; ListNode pre = head; while (fast != null && fast.next != null) { pre = slow; slow = slow.next; fast = fast.next.next; } return pre; }
8. 두 갈래 찾기 트리에서 두 개의 노드를 찾아서 그것들의 합을 하나의 값으로 지정한다
653. Two Sum IV - Input is a BST (Easy) Input:
5
/ \
3 6
/ \ \
2 4 7
Target = 9
Output: True
중순으로 질서 있는 그룹을 훑어본 후 두 바늘을 이용하여 그룹을 찾습니다.
이 문제는 좌우자수 두 부분에 나누어 이런 사상을 처리할 수 없다는 것을 주의해야 한다. 왜냐하면 두 개의 구하고자 하는 노드가 좌우자수에 있을 수 있기 때문이다.public boolean findTarget(TreeNode root, int k) {
List<Integer> nums = new ArrayList<>(); inOrder(root, nums); int i = 0, j = nums.size() - 1; while (i < j) { int sum = nums.get(i) + nums.get(j); if (sum == k) return true; if (sum < k) i++; else j--; } return false; } private void inOrder(TreeNode root, List<Integer> nums) { if (root == null) return; inOrder(root.left, nums); nums.add(root.val); inOrder(root.right, nums); }
9. 두 갈래 찾기 트리에서 두 노드 차이의 최소 절대값 찾기
530. Minimum Absolute Difference in BST (Easy) Input:
1
\
3
/
2
Output:
1
두 갈래를 이용하여 트리의 중서 역행이 질서정연한 성질을 찾아내고 중서 역행 중 가까운 두 노드의 차이의 절대값을 계산하여 최소값을 얻는다.private int minDiff = Integer.MAX_VALUE; private TreeNode preNode = null; public int getMinimumDifference(TreeNode root) { inOrder(root); return minDiff; } private void inOrder(TreeNode node) { if (node == null) return; inOrder(node.left); if (preNode != null) minDiff = Math.min(minDiff, node.val - preNode.val); preNode = node; inOrder(node.right); }
10. 두 갈래 찾기 트리에서 가장 많이 나타나는 값 찾기
501. Find Mode in Binary Search Tree (Easy) 1
\
2
/
2
return [2].
답은 한 가지가 아닐 수도 있다. 즉, 여러 개의 값이 나타나는 횟수만큼 많을 수도 있다.private int curCnt = 1;
private int maxCnt = 1; private TreeNode preNode = null; public int[] findMode(TreeNode root) { List<Integer> maxCntNums = new ArrayList<>(); inOrder(root, maxCntNums); int[] ret = new int[maxCntNums.size()]; int idx = 0; for (int num : maxCntNums) { ret[idx++] = num; } return ret; } private void inOrder(TreeNode node, List<Integer> nums) { if (node == null) return; inOrder(node.left, nums); if (preNode != null) { if (preNode.val == node.val) curCnt++; else curCnt = 1; } if (curCnt > maxCnt) { maxCnt = curCnt; nums.clear(); nums.add(node.val); } else if (curCnt == maxCnt) { nums.add(node.val); } preNode = node; inOrder(node.right, nums); }
Trie
트리, 접두사 트리나 사전 트리라고도 하는데 문자열이 존재하거나 어떤 문자열 접두사가 있는지 판단하는 데 쓰인다.
1. 하나의 Trie 구현
208. Implement Trie (Prefix Tree) (Medium) class Trie {
private class Node {
Node[] childs = new Node[26]; boolean isLeaf; } private Node root = new Node(); public Trie() { } public void insert(String word) { insert(word, root); } private void insert(String word, Node node) { if (node == null) return; if (word.length() == 0) { node.isLeaf = true; return; } int index = indexForChar(word.charAt(0)); if (node.childs[index] == null) { node.childs[index] = new Node(); } insert(word.substring(1), node.childs[index]); } public boolean search(String word) { return search(word, root); } private boolean search(String word, Node node) { if (node == null) return false; if (word.length() == 0) return node.isLeaf; int index = indexForChar(word.charAt(0)); return search(word.substring(1), node.childs[index]); } public boolean startsWith(String prefix) { return startWith(prefix, root); } private boolean startWith(String prefix, Node node) { if (node == null) return false; if (prefix.length() == 0) return true; int index = indexForChar(prefix.charAt(0)); return startWith(prefix.substring(1), node.childs[index]); } private int indexForChar(char c) { return c - 'a'; } }
2. 접두사와
677. Map Sum Pairs (Medium) Input: insert("apple", 3), Output: Null
Input: sum("ap"), Output: 3
Input: insert("app", 2), Output: Null
Input: sum("ap"), Output: 5
class MapSum {
private class Node {
Node[] child = new Node[26]; int value; } private Node root = new Node(); public MapSum() { } public void insert(String key, int val) { insert(key, root, val); } private void insert(String key, Node node, int val) { if (node == null) return; if (key.length() == 0) { node.value = val; return; } int index = indexForChar(key.charAt(0)); if (node.child[index] == null) { node.child[index] = new Node(); } insert(key.substring(1), node.child[index], val); } public int sum(String prefix) { return sum(prefix, root); } private int sum(String prefix, Node node) { if (node == null) return 0; if (prefix.length() != 0) { int index = indexForChar(prefix.charAt(0)); return sum(prefix.substring(1), node.child[index]); } int sum = node.value; for (Node child : node.child) { sum += sum(prefix, child); } return sum; } private int indexForChar(char c) { return c - 'a'; } }
다음으로 전송:https://www.cnblogs.com/daimasanjiaomao/p/11009120.html
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
다양한 언어의 JSON
JSON은 Javascript 표기법을 사용하여 데이터 구조를 레이아웃하는 데이터 형식입니다.
그러나 Javascript가 코드에서 이러한 구조를 나타낼 수 있는 유일한 언어는 아닙니다.
저는 일반적으로 '객체'{}...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.
Input:
3
/ \
0 4
\
2
/
1
L = 1
R = 3
Output:
3
/
2
/
1
public TreeNode trimBST(TreeNode root, int L, int R) { if (root == null) return null; if (root.val > R) return trimBST(root.left, L, R); if (root.val < L) return trimBST(root.right, L, R); root.left = trimBST(root.left, L, R); root.right = trimBST(root.right, L, R); return root; }
private int cnt = 0;
private int val; public int kthSmallest(TreeNode root, int k) { inOrder(root, k); return val; } private void inOrder(TreeNode node, int k) { if (node == null) return; inOrder(node.left, k); cnt++; if (cnt == k) { val = node.val; return; } inOrder(node.right, k); }
public int kthSmallest(TreeNode root, int k) {
int leftCnt = count(root.left); if (leftCnt == k - 1) return root.val; if (leftCnt > k - 1) return kthSmallest(root.left, k); return kthSmallest(root.right, k - leftCnt - 1); } private int count(TreeNode node) { if (node == null) return 0; return 1 + count(node.left) + count(node.right); }
Input: The root of a Binary Search Tree like this:
5
/ \
2 13
Output: The root of a Greater Tree like this:
18
/ \
20 13
private int sum = 0;
public TreeNode convertBST(TreeNode root) { traver(root); return root; } private void traver(TreeNode node) { if (node == null) return; traver(node.right); sum += node.val; node.val = sum; traver(node.left); }
_______6______
/ \
___2__ ___8__
/ \ / \
0 4 7 9
/ \
3 5
For example, the lowest common ancestor (LCA) of nodes 2 and 8 is 6. Another example is LCA of nodes 2 and 4 is 2, since a node can be a descendant of itself according to the LCA definition.
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
if (root.val > p.val && root.val > q.val) return lowestCommonAncestor(root.left, p, q); if (root.val < p.val && root.val < q.val) return lowestCommonAncestor(root.right, p, q); return root; }
_______3______
/ \
___5__ ___1__
/ \ / \
6 2 0 8
/ \
7 4
For example, the lowest common ancestor (LCA) of nodes 5 and 1 is 3. Another example is LCA of nodes 5 and 4 is 5, since a node can be a descendant of itself according to the LCA definition.
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
if (root == null || root == p || root == q) return root; TreeNode left = lowestCommonAncestor(root.left, p, q); TreeNode right = lowestCommonAncestor(root.right, p, q); return left == null ? right : right == null ? left : root; }
public TreeNode sortedArrayToBST(int[] nums) {
return toBST(nums, 0, nums.length - 1); } private TreeNode toBST(int[] nums, int sIdx, int eIdx){ if (sIdx > eIdx) return null; int mIdx = (sIdx + eIdx) / 2; TreeNode root = new TreeNode(nums[mIdx]); root.left = toBST(nums, sIdx, mIdx - 1); root.right = toBST(nums, mIdx + 1, eIdx); return root; }
Given the sorted linked list: [-10,-3,0,5,9],
One possible answer is: [0,-3,9,-10,null,5], which represents the following height balanced BST:
0
/ \
-3 9
/ /
-10 5
public TreeNode sortedListToBST(ListNode head) {
if (head == null) return null; if (head.next == null) return new TreeNode(head.val); ListNode preMid = preMid(head); ListNode mid = preMid.next; preMid.next = null; // TreeNode t = new TreeNode(mid.val); t.left = sortedListToBST(head); t.right = sortedListToBST(mid.next); return t; } private ListNode preMid(ListNode head) { ListNode slow = head, fast = head.next; ListNode pre = head; while (fast != null && fast.next != null) { pre = slow; slow = slow.next; fast = fast.next.next; } return pre; }
Input:
5
/ \
3 6
/ \ \
2 4 7
Target = 9
Output: True
public boolean findTarget(TreeNode root, int k) {
List<Integer> nums = new ArrayList<>(); inOrder(root, nums); int i = 0, j = nums.size() - 1; while (i < j) { int sum = nums.get(i) + nums.get(j); if (sum == k) return true; if (sum < k) i++; else j--; } return false; } private void inOrder(TreeNode root, List<Integer> nums) { if (root == null) return; inOrder(root.left, nums); nums.add(root.val); inOrder(root.right, nums); }
Input:
1
\
3
/
2
Output:
1
private int minDiff = Integer.MAX_VALUE; private TreeNode preNode = null; public int getMinimumDifference(TreeNode root) { inOrder(root); return minDiff; } private void inOrder(TreeNode node) { if (node == null) return; inOrder(node.left); if (preNode != null) minDiff = Math.min(minDiff, node.val - preNode.val); preNode = node; inOrder(node.right); }
1
\
2
/
2
return [2].
private int curCnt = 1;
private int maxCnt = 1; private TreeNode preNode = null; public int[] findMode(TreeNode root) { List<Integer> maxCntNums = new ArrayList<>(); inOrder(root, maxCntNums); int[] ret = new int[maxCntNums.size()]; int idx = 0; for (int num : maxCntNums) { ret[idx++] = num; } return ret; } private void inOrder(TreeNode node, List<Integer> nums) { if (node == null) return; inOrder(node.left, nums); if (preNode != null) { if (preNode.val == node.val) curCnt++; else curCnt = 1; } if (curCnt > maxCnt) { maxCnt = curCnt; nums.clear(); nums.add(node.val); } else if (curCnt == maxCnt) { nums.add(node.val); } preNode = node; inOrder(node.right, nums); }
트리, 접두사 트리나 사전 트리라고도 하는데 문자열이 존재하거나 어떤 문자열 접두사가 있는지 판단하는 데 쓰인다.
1. 하나의 Trie 구현
208. Implement Trie (Prefix Tree) (Medium)
class Trie {
private class Node {
Node[] childs = new Node[26]; boolean isLeaf; } private Node root = new Node(); public Trie() { } public void insert(String word) { insert(word, root); } private void insert(String word, Node node) { if (node == null) return; if (word.length() == 0) { node.isLeaf = true; return; } int index = indexForChar(word.charAt(0)); if (node.childs[index] == null) { node.childs[index] = new Node(); } insert(word.substring(1), node.childs[index]); } public boolean search(String word) { return search(word, root); } private boolean search(String word, Node node) { if (node == null) return false; if (word.length() == 0) return node.isLeaf; int index = indexForChar(word.charAt(0)); return search(word.substring(1), node.childs[index]); } public boolean startsWith(String prefix) { return startWith(prefix, root); } private boolean startWith(String prefix, Node node) { if (node == null) return false; if (prefix.length() == 0) return true; int index = indexForChar(prefix.charAt(0)); return startWith(prefix.substring(1), node.childs[index]); } private int indexForChar(char c) { return c - 'a'; } }
2. 접두사와
677. Map Sum Pairs (Medium)
Input: insert("apple", 3), Output: Null
Input: sum("ap"), Output: 3
Input: insert("app", 2), Output: Null
Input: sum("ap"), Output: 5
class MapSum {
private class Node {
Node[] child = new Node[26]; int value; } private Node root = new Node(); public MapSum() { } public void insert(String key, int val) { insert(key, root, val); } private void insert(String key, Node node, int val) { if (node == null) return; if (key.length() == 0) { node.value = val; return; } int index = indexForChar(key.charAt(0)); if (node.child[index] == null) { node.child[index] = new Node(); } insert(key.substring(1), node.child[index], val); } public int sum(String prefix) { return sum(prefix, root); } private int sum(String prefix, Node node) { if (node == null) return 0; if (prefix.length() != 0) { int index = indexForChar(prefix.charAt(0)); return sum(prefix.substring(1), node.child[index]); } int sum = node.value; for (Node child : node.child) { sum += sum(prefix, child); } return sum; } private int indexForChar(char c) { return c - 'a'; } }
다음으로 전송:https://www.cnblogs.com/daimasanjiaomao/p/11009120.html
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
다양한 언어의 JSONJSON은 Javascript 표기법을 사용하여 데이터 구조를 레이아웃하는 데이터 형식입니다. 그러나 Javascript가 코드에서 이러한 구조를 나타낼 수 있는 유일한 언어는 아닙니다. 저는 일반적으로 '객체'{}...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.