-
-
Notifications
You must be signed in to change notification settings - Fork 195
[forest000014] Week 11 #1042
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
[forest000014] Week 11 #1042
Changes from all commits
Commits
Show all changes
10 commits
Select commit
Hold shift + click to select a range
bf3365b
DaleStudy#227 Maximum Depth of Binary Tree
forest000014 63805ba
DaleStudy#247 Reorder List
forest000014 236f699
DaleStudy#262 Graph Valid Tree
forest000014 22a3bee
DaleStudy#278 Merge Intervals
forest000014 3babc3f
DaleStudy#287 Binary Tree Maximum Path Sum
forest000014 867c4f8
DaleStudy#241 3Sum
forest000014 e484116
DaleStudy#241 3Sum - Dale 풀이 참고
forest000014 ad17299
DaleStudy#253 Construct Binary Tree from Preorder and Inorder Traversal
forest000014 15c99cd
DaleStudy#268 Decode Ways
forest000014 cd23cc2
DaleStudy#276 Jump Game
forest000014 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
/* | ||
# Time Complexity: O(n^2) | ||
# Space Complexity: O(1) | ||
*/ | ||
|
||
class Solution { | ||
public List<List<Integer>> threeSum1(int[] nums) { // solution 1 | ||
int n = nums.length; | ||
Arrays.sort(nums); | ||
Set<List<Integer>> ans = new HashSet<>(); | ||
|
||
for (int i = 0; i < n - 2; i++) { | ||
for (int j = i + 1; j < n - 1; j++) { | ||
int target = -nums[i] - nums[j]; // nums[i], nums[j]와 더해서 합이 0이 되기 위해 nums[k]가 가져야하는 값 | ||
int k = -1; | ||
int l = j + 1; | ||
int r = n - 1; | ||
while (l <= r) { | ||
int m = (r - l) / 2 + l; | ||
if (nums[m] == target) { | ||
k = m; | ||
break; | ||
} else if (nums[m] < target) { | ||
l = m + 1; | ||
} else { | ||
r = m - 1; | ||
} | ||
} | ||
if (k != -1) { // binary search에서 target을 찾은 경우 | ||
ans.add(new ArrayList<>(Arrays.asList(nums[i], nums[j], nums[k]))); | ||
} | ||
} | ||
} | ||
|
||
return new ArrayList<>(ans); | ||
} | ||
|
||
public List<List<Integer>> threeSum(int[] nums) { // solution 2 | ||
int n = nums.length; | ||
Arrays.sort(nums); | ||
Set<List<Integer>> ans = new HashSet<>(); | ||
|
||
for (int i = 0; i < n - 2; i++) { | ||
int l = i + 1; | ||
int r = n - 1; | ||
int target = -nums[i]; | ||
while (l < r) { | ||
int sum = nums[l] + nums[r]; | ||
if (sum == target) { | ||
ans.add(new ArrayList<>(Arrays.asList(nums[i], nums[l], nums[r]))); | ||
l++; | ||
r--; // 또 다른 (l, r) 조합이 있을 수 있으므로, loop를 계속 이어간다. | ||
} else if (sum < target) { | ||
l++; | ||
} else { | ||
r--; | ||
} | ||
} | ||
} | ||
|
||
return new ArrayList<>(ans); | ||
} | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
/* | ||
# Time Complexity: O(n) | ||
# Space Complexity: O(n) | ||
- 재귀 호출 내부에서 left, right 변수를 사용하고, 재귀 호출 최대 깊이는 n이므로 | ||
# Solution | ||
전체 문제를 각 subtree에 대한 문제로 쪼개어 생각할 수 있습니다. | ||
임의의 노드 x에 대해, x의 왼쪽 자식을 x_l, x의 오른쪽 자식을 x_r, x의 값을 x.val이라고 정의하겠습니다. | ||
x를 root로 하는 subtree에서 'x를 path의 한쪽 끝으로 하는 path sum 중 최대값'을 dp[x]라고 정의하겠습니다. | ||
그러면 dp[x] = max(max(0, dp[x_l]) + x.val, max(0, dp[x_r]) + x.val) 로 구할 수 있습니다. (subtree의 dp 값이 음수인 경우는 버리면 되기 때문에.) | ||
이제 root로부터 출발해서 DFS로 전체 노드를 순회하며 이 점화식을 적용하면, 전체 tree에 대해 dp값을 구할 수 있습니다. | ||
단, 문제에서 원하는 답은 root를 반드시 path의 한쪽 끝으로 원하는 것은 아니고, 심지어 root가 path에 포함되지 않아도 되기 때문에, | ||
어중간한(?) (= root를 path에 포함하지 않는) path도 고려할 필요가 있는데요. | ||
이를 고려하기 위해, 각 재귀 함수 호출마다 max(0, dp[x_l]) + root.val + max(0, dp[x_r]) 값이 정답이 될 수 있는지 체크하는 과정이 필요합니다. | ||
*/ | ||
/** | ||
* Definition for a binary tree node. | ||
* public class TreeNode { | ||
* int val; | ||
* TreeNode left; | ||
* TreeNode right; | ||
* TreeNode() {} | ||
* TreeNode(int val) { this.val = val; } | ||
* TreeNode(int val, TreeNode left, TreeNode right) { | ||
* this.val = val; | ||
* this.left = left; | ||
* this.right = right; | ||
* } | ||
* } | ||
*/ | ||
class Solution { | ||
public int ans = -30_000_001; | ||
public int maxPathSum(TreeNode root) { | ||
maxInTree(root); | ||
|
||
return ans; | ||
} | ||
|
||
public int maxInTree(TreeNode root) { | ||
if (root == null) { | ||
return 0; | ||
} | ||
|
||
int left = Math.max(0, maxInTree(root.left)); | ||
int right = Math.max(0, maxInTree(root.right)); | ||
|
||
ans = Math.max(ans, left + root.val + right); | ||
|
||
return root.val + Math.max(left, right); | ||
} | ||
} |
46 changes: 46 additions & 0 deletions
46
construct-binary-tree-from-preorder-and-inorder-traversal/forest000014.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
/** | ||
이 문제는 힌트의 도움을 받아서 풀었습니다. | ||
- preorder의 첫 원소는 항상 root node임 | ||
- inorder에서 root node의 왼쪽의 원소들은 root node의 왼쪽 subtree, 오른쪽 원소들은 오른쪽 subtree임 | ||
- 왼쪽 subtree와 오른쪽 subtree는 각각 preorder에서 연속하게 있음. (root, 왼쪽 subtree, 오른쪽 subtree 순) | ||
|
||
시간 복잡도 : O(n) | ||
공간 복잡도 : O(n^2) | ||
(skewed tree의 경우, 최악의 공간 복잡도를 가짐) | ||
*/ | ||
class Solution { | ||
public TreeNode buildTree(int[] preorder, int[] inorder) { | ||
if (preorder.length == 0) { | ||
return null; | ||
} | ||
if (preorder.length == 1) { | ||
return new TreeNode(preorder[0]); | ||
} | ||
int currIdx; | ||
for (currIdx = 0; currIdx < inorder.length; currIdx++) { | ||
if (inorder[currIdx] == preorder[0]) { | ||
break; | ||
} | ||
} | ||
|
||
int[] lp = new int[currIdx]; | ||
int[] li = new int[currIdx]; | ||
int[] rp = new int[inorder.length - currIdx - 1]; | ||
int[] ri = new int[inorder.length - currIdx - 1]; | ||
for (int i = 0; i < currIdx; i++) { | ||
lp[i] = preorder[i + 1]; | ||
li[i] = inorder[i]; | ||
} | ||
for (int i = currIdx + 1; i < inorder.length; i++) { | ||
rp[i - currIdx - 1] = preorder[i]; | ||
ri[i - currIdx - 1] = inorder[i]; | ||
} | ||
|
||
TreeNode lc = buildTree(lp, li); | ||
TreeNode rc = buildTree(rp, ri); | ||
|
||
TreeNode curr = new TreeNode(preorder[0], lc, rc); | ||
|
||
return curr; | ||
} | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
/* | ||
# Time Complexity: O(n) | ||
# Space Complexity: O(n) | ||
*/ | ||
class Solution { | ||
|
||
private boolean check12(char ch) { | ||
return (ch == '1' || ch == '2'); | ||
} | ||
|
||
private boolean check1(char ch) { | ||
return ch == '1'; | ||
} | ||
|
||
private boolean check2(char ch) { | ||
return ch == '2'; | ||
} | ||
|
||
private boolean check0(char ch) { | ||
return ch == '0'; | ||
} | ||
|
||
private boolean check6(char ch) { | ||
return ch <= '6'; | ||
} | ||
|
||
public int numDecodings(String s) { | ||
int n = s.length(); | ||
|
||
if (n == 0) | ||
return 0; | ||
|
||
int[] dp = new int[n + 1]; | ||
|
||
if (check0(s.charAt(0))) | ||
return 0; | ||
|
||
dp[0] = 1; | ||
dp[1] = 1; | ||
if (n == 1) | ||
return dp[1]; | ||
|
||
for (int i = 1; i < n; i++) { | ||
if (check0(s.charAt(i)) && !check12(s.charAt(i - 1))) | ||
return 0; | ||
|
||
if (!check0(s.charAt(i))) | ||
dp[i + 1] = dp[i]; | ||
|
||
if (check1(s.charAt(i - 1)) || (check6(s.charAt(i)) && check2(s.charAt(i - 1)))) | ||
dp[i + 1] += dp[i - 1]; | ||
} | ||
return dp[n]; | ||
} | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
/* | ||
# Time Complexity: O(n) | ||
# Space Complexity: O(n + m) | ||
- m은 edges.length | ||
|
||
# Solution | ||
edges[0][0]에서 출발하여 인접한 모든 edge를 DFS로 순회한다. | ||
- cycle이 있는 경우 (이미 방문한 적이 있는 node를 재방문) | ||
- 순회를 마쳤는데 방문하지 않은 node가 있는 경우 | ||
위 2경우는 invalid tree이고, 그렇지 않으면 valid tree이다. | ||
*/ | ||
class Solution { | ||
public ArrayList<ArrayList<Integer>> adj = new ArrayList<>(); | ||
public boolean[] visited; | ||
public boolean validTree(int n, int[][] edges) { | ||
if (edges.length == 0) { | ||
return n == 1; | ||
} | ||
|
||
visited = new boolean[n]; | ||
|
||
for (int i = 0; i < n; i++) { | ||
adj.add(new ArrayList<Integer>()); | ||
} | ||
|
||
for (int i = 0; i < edges.length; i++) { | ||
int a = edges[i][0]; | ||
int b = edges[i][1]; | ||
adj.get(a).add(b); | ||
adj.get(b).add(a); | ||
} | ||
|
||
if (!dfs(-1, edges[0][0])) { | ||
return false; | ||
} | ||
|
||
for (int i = 0; i < n; i++) { | ||
if (!visited[i]) { | ||
return false; | ||
} | ||
} | ||
|
||
return true; | ||
} | ||
|
||
public boolean dfs(int prev, int curr) { | ||
visited[curr] = true; | ||
|
||
for (Integer next : adj.get(curr)) { | ||
if (next == prev) { | ||
continue; | ||
} | ||
|
||
if (visited[next]) { | ||
return false; | ||
} | ||
|
||
if (!dfs(curr, next)) { | ||
return false; | ||
} | ||
} | ||
|
||
return true; | ||
} | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
/* | ||
# Time Complexity: O(n) | ||
# Space Complexity: O(n) | ||
*/ | ||
|
||
class Solution { | ||
public boolean canJump(int[] nums) { | ||
int n = nums.length; | ||
boolean[] dp = new boolean[n]; | ||
|
||
dp[0] = true; | ||
|
||
for (int i = 0; i < n; i++) { | ||
if (!dp[i]) return false; | ||
int j = Math.min(n - 1, i + nums[i]); | ||
for (; j >= i + 1; j--) { | ||
if (dp[j]) break; | ||
dp[j] = true; | ||
} | ||
} | ||
|
||
return true; | ||
} | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
/* | ||
# Time Complexity: O(n) | ||
# Space Complexity: O(1) | ||
*/ | ||
/** | ||
* Definition for a binary tree node. | ||
* public class TreeNode { | ||
* int val; | ||
* TreeNode left; | ||
* TreeNode right; | ||
* TreeNode() {} | ||
* TreeNode(int val) { this.val = val; } | ||
* TreeNode(int val, TreeNode left, TreeNode right) { | ||
* this.val = val; | ||
* this.left = left; | ||
* this.right = right; | ||
* } | ||
* } | ||
*/ | ||
class Solution { | ||
public int maxDepth(TreeNode root) { | ||
if (root == null) { | ||
return 0; | ||
} | ||
|
||
return Math.max(maxDepth(root.left), maxDepth(root.right)) + 1; | ||
} | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
/* | ||
# Time Complexity: O(nlogn) | ||
# Space Complexity: O(n) | ||
*/ | ||
|
||
class Solution { | ||
public int[][] merge(int[][] intervals) { | ||
int n = intervals.length; | ||
|
||
Arrays.sort(intervals, (a, b) -> a[0] - b[0]); | ||
|
||
ArrayList<int[]> ans = new ArrayList<>(); | ||
ans.add(new int[2]); | ||
ans.get(0)[0] = intervals[0][0]; | ||
ans.get(0)[1] = intervals[0][1]; | ||
|
||
for (int i = 1; i < n; i++) { | ||
if (ans.get(ans.size() - 1)[1] < intervals[i][0]) { | ||
ans.add(new int[2]); | ||
ans.get(ans.size() - 1)[0] = intervals[i][0]; | ||
ans.get(ans.size() - 1)[1] = intervals[i][1]; | ||
} else { | ||
ans.get(ans.size() - 1)[1] = Math.max(ans.get(ans.size() - 1)[1], intervals[i][1]); | ||
} | ||
} | ||
|
||
return ans.toArray(new int[ans.size()][]); | ||
} | ||
} |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
int 에서 최솟값을 초기화 하는거라면 Integer.MIN_VALUE를 사용하면 어떨까요?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
아아 넵 그런 방법이 있었군요! 다음 번 풀이부터는 사용해보겠습니다 :)