forked from DaleStudy/leetcode-study
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request DaleStudy#1042 from forest000014/main
[forest000014] Week 11
- Loading branch information
Showing
9 changed files
with
409 additions
and
0 deletions.
There are no files selected for viewing
This file contains 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 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 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 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 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 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 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 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.