Skip to content

Commit 74f06db

Browse files
authored
[samcho0608] WEEK 02 solutions (#2032)
[samcho0608] WEEK 02 solutions
2 parents b1ba303 + bbe521d commit 74f06db

File tree

5 files changed

+306
-0
lines changed

5 files changed

+306
-0
lines changed

3sum/samcho0608.java

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
import java.util.ArrayList;
2+
import java.util.Arrays;
3+
import java.util.List;
4+
5+
// link: https://leetcode.com/problems/3sum/
6+
// difficulty: Medium
7+
class Solution {
8+
// Problem:
9+
// * return: all triplets of elements in nums such that the sum == 0 (indices must differ)
10+
// Solution:
11+
// * Time Complexity: O(N^2)
12+
// * Space Complexity: O(1)
13+
public List<List<Integer>> threeSum(int[] nums) {
14+
// sort for simplicity
15+
// Time Complexity: O(N log N)
16+
Arrays.sort(nums);
17+
18+
List<List<Integer>> answers = new ArrayList<>();
19+
20+
// if there are only positive or only negative numbers, there exist no solution
21+
if(nums[0] > 0 || nums[nums.length-1] < 0) return answers;
22+
23+
24+
25+
// Time Complexity: O(N^2)
26+
// * for loop * inner while loop = O(N) * O(N) = O(N^2)
27+
28+
// nums[i]: first of the triplet
29+
// * skip positive because the other two will also be positive
30+
for(int i = 0; i < nums.length && nums[i] <= 0; i++) {
31+
// skip if same first of the triplet met
32+
if(i != 0 && nums[i] == nums[i-1]) continue;
33+
34+
int numI = nums[i];
35+
36+
int left = i + 1;
37+
int right = nums.length - 1;
38+
39+
// Time Complexity: O(N)
40+
while(left < right) {
41+
int numLeft = nums[left];
42+
int numRight = nums[right];
43+
44+
int sum = numI + numLeft + numRight;
45+
46+
if(sum == 0) {
47+
answers.add(Arrays.asList(numI, numLeft, numRight));
48+
49+
// skip same lefts and rights two prevent duplicate
50+
// * must update both left and right
51+
// * e.g. if only left is moved, newNumLeft = 0 - (numI + numRight) and that can only be numLeft that's already visited
52+
// * Time Complexity: O(1) because there is no actual operation other than skipping
53+
while(left < nums.length && nums[left] == numLeft) left++;
54+
55+
while(right > left && nums[right] == numRight) right--;
56+
} else if(sum > 0) {
57+
right--;
58+
} else {
59+
left++;
60+
}
61+
}
62+
}
63+
64+
return answers;
65+
}
66+
}

climbing-stairs/samcho0608.java

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
class Solution {
2+
// Problem:
3+
// * can take 1 or 2 steps
4+
// * return: how many distinct ways to climb to the top(n)
5+
// Solution:
6+
// * Time Complexity: O(N)
7+
// * due to memoization(DP)
8+
// * Space Complexity: O(N)
9+
public int climbStairs(int n) {
10+
// memo[i] = distinct steps to reach ith step
11+
int[] memo = new int[n + 1];
12+
memo[0] = 1;
13+
memo[1] = 1;
14+
15+
for(int i = 2; i < n+1; i++) {
16+
memo[i] = memo[i-1] + memo[i-2];
17+
}
18+
19+
return memo[n];
20+
}
21+
}
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
// link: https://leetcode.com/problems/product-of-array-except-self/submissions/1831301674/
2+
// difficulty: Medium
3+
class Solution1 {
4+
// Problem:
5+
// * return: array where answer[i] = product of all elements except nums[i]
6+
// Solution:
7+
// * Time Complexity: O(N)
8+
// * Space Complexity: O(N)
9+
public int[] productExceptSelf(int[] nums) {
10+
int n = nums.length;
11+
12+
// prefixProds[i] = prod of all elements upto i (exclusive)
13+
int[] prefixProds = new int[n];
14+
for(int i = 0; i < n; i++) {
15+
if(i == 0) {
16+
prefixProds[i] = 1;
17+
continue;
18+
}
19+
20+
prefixProds[i] = prefixProds[i-1] * nums[i-1];
21+
}
22+
23+
// suffixProds[i] = prod of all elements from end to i (exclusive)
24+
int[] suffixProds = new int[n];
25+
for(int i = n - 1; i >= 0; i--) {
26+
if(i == n - 1) {
27+
suffixProds[i] = 1;
28+
continue;
29+
}
30+
31+
suffixProds[i] = suffixProds[i+1] * nums[i+1];
32+
}
33+
34+
// multiply prefix and suffix prods to find answers
35+
int[] answers = new int[n];
36+
for(int i = 0; i< n;i++) {
37+
answers[i] = prefixProds[i] * suffixProds[i];
38+
}
39+
40+
return answers;
41+
}
42+
}
43+
44+
// uses only 1 array whereas solution 1 uses 3
45+
class Solution2 {
46+
// Problem:
47+
// * return: array where answer[i] = product of all elements except nums[i]
48+
// Solution:
49+
// * Time Complexity: O(N)
50+
// * Space Complexity: O(N)
51+
public int[] productExceptSelf(int[] nums) {
52+
int n = nums.length;
53+
54+
// prefixProds[i] = prod of all elements upto i (exclusive)
55+
int[] answers = new int[n];
56+
for(int i = 0; i < n; i++) {
57+
if(i == 0) {
58+
answers[i] = 1;
59+
continue;
60+
}
61+
62+
answers[i] = answers[i-1] * nums[i-1];
63+
}
64+
65+
// use a single variable for suffix product
66+
int suffixProd = 1;
67+
for(int i = n - 2; i >= 0; i--) {
68+
suffixProd *= nums[i+1];
69+
answers[i] *= suffixProd;
70+
}
71+
72+
return answers;
73+
}
74+
}
75+

valid-anagram/samcho0608.java

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
import java.util.HashMap;
2+
3+
// link: https://leetcode.com/problems/valid-anagram/
4+
// difficulty: Easy
5+
class Solution1 {
6+
// Problem:
7+
// * return: is t an anagram of s
8+
public boolean isAnagram(String s, String t) {
9+
if(s.length() != t.length()) return false;
10+
11+
int n = s.length();
12+
13+
// Space Complexity: O(N)
14+
HashMap<Character, Integer> freqS = new HashMap<>();
15+
HashMap<Character, Integer> freqT = new HashMap<>();
16+
17+
// Time Complexity: O(N)
18+
for(int i = 0; i < n; i++) {
19+
char charS = s.charAt(i);
20+
freqS.put(charS, freqS.getOrDefault(charS, 0) + 1);
21+
22+
char charT = t.charAt(i);
23+
freqT.put(charT, freqT.getOrDefault(charT, 0) + 1);
24+
}
25+
26+
// Time Complexity: O(N)
27+
for(var entryS: freqS.entrySet()) {
28+
int cntT = freqT.getOrDefault(entryS.getKey(), 0);
29+
if(cntT != entryS.getValue()) return false;
30+
}
31+
32+
return true;
33+
}
34+
}
35+
36+
// Map 하나만 사용하는 개선된 방식
37+
class Solution2 {
38+
// Problem:
39+
// * return: is t an anagram of s
40+
public boolean isAnagram(String s, String t) {
41+
if(s.length() != t.length()) return false;
42+
43+
int n = s.length();
44+
45+
// Space Complexity: O(N)
46+
HashMap<Character, Integer> freq = new HashMap<>();
47+
48+
// Time Complexity: O(N)
49+
for(int i = 0; i < n; i++) {
50+
char charS = s.charAt(i);
51+
freq.put(charS, freq.getOrDefault(charS, 0) + 1);
52+
53+
char charT = t.charAt(i);
54+
freq.put(charT, freq.getOrDefault(charT, 0) - 1);
55+
}
56+
57+
// Time Complexity: O(N)
58+
for(int count: freq.values()) {
59+
if(count != 0) return false;
60+
}
61+
62+
return true;
63+
}
64+
}
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
// link: https://leetcode.com/problems/validate-binary-search-tree/description/
2+
// difficulty: Medium
3+
/**
4+
* Definition for a binary tree node.
5+
* public class TreeNode {
6+
* int val;
7+
* TreeNode left;
8+
* TreeNode right;
9+
* TreeNode() {}
10+
* TreeNode(int val) { this.val = val; }
11+
* TreeNode(int val, TreeNode left, TreeNode right) {
12+
* this.val = val;
13+
* this.left = left;
14+
* this.right = right;
15+
* }
16+
* }
17+
*/
18+
class Solution1 {
19+
// Problem:
20+
// * return: check if tree is a valid BST
21+
// * left subtree contains keys strictly less than node's key
22+
// * right subtree contains keys strictly greater than node's key
23+
// * recursive structure
24+
// Solution:
25+
// * Time Complexity: O(N)
26+
// * Space Complexity(in terms of call stack):
27+
// * O(N) if skewed
28+
// * O(log N) if not skewed
29+
public boolean isValidBST(TreeNode root) {
30+
// checklist:
31+
// * is subtree a valid bst
32+
// * left subtree : is max value of subtree less than node
33+
// * right subtree : is min value of subtree greater than node
34+
return isValid(root, null, null);
35+
}
36+
37+
private boolean isValid(TreeNode node, Integer min, Integer max) {
38+
if(node == null) return true;
39+
40+
int val = node.val;
41+
42+
if(min != null && val <= min) return false;
43+
if(max != null && val >= max) return false;
44+
45+
if(!isValid(node.left, min, val)) return false;
46+
if(!isValid(node.right, val, max)) return false;
47+
48+
return true;
49+
}
50+
}
51+
52+
// in-order traversal approach
53+
// * reads from left-most to right (strictly increasing val order expected)
54+
class Solution2 {
55+
private Integer prev;
56+
57+
// Solution:
58+
// * Time Complexity: O(N)
59+
// * Space Complexity(in terms of call stack):
60+
// * O(N) if skewed
61+
// * O(log N) if not skewed
62+
public boolean isValidBST(TreeNode root) {
63+
prev = null;
64+
return inorder(root);
65+
}
66+
67+
private boolean inorder(TreeNode node) {
68+
// reached end without failure
69+
if(node == null) return true;
70+
71+
// inorder so travel left first
72+
if(!inorder(node.left)) return false;
73+
74+
// if node value is not greater than prev, it isn't a BST in in-order
75+
if(prev != null && node.val <= prev) return false;
76+
prev = node.val;
77+
78+
return inorder(node.right);
79+
}
80+
}

0 commit comments

Comments
 (0)