Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
66 changes: 66 additions & 0 deletions 3sum/samcho0608.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

// link: https://leetcode.com/problems/3sum/
// difficulty: Medium
class Solution {
// Problem:
// * return: all triplets of elements in nums such that the sum == 0 (indices must differ)
// Solution:
// * Time Complexity: O(N^2)
// * Space Complexity: O(1)
public List<List<Integer>> threeSum(int[] nums) {
// sort for simplicity
// Time Complexity: O(N log N)
Arrays.sort(nums);

List<List<Integer>> answers = new ArrayList<>();

// if there are only positive or only negative numbers, there exist no solution
if(nums[0] > 0 || nums[nums.length-1] < 0) return answers;



// Time Complexity: O(N^2)
// * for loop * inner while loop = O(N) * O(N) = O(N^2)

// nums[i]: first of the triplet
// * skip positive because the other two will also be positive
for(int i = 0; i < nums.length && nums[i] <= 0; i++) {
// skip if same first of the triplet met
if(i != 0 && nums[i] == nums[i-1]) continue;

int numI = nums[i];

int left = i + 1;
int right = nums.length - 1;

// Time Complexity: O(N)
while(left < right) {
int numLeft = nums[left];
int numRight = nums[right];

int sum = numI + numLeft + numRight;

if(sum == 0) {
answers.add(Arrays.asList(numI, numLeft, numRight));

// skip same lefts and rights two prevent duplicate
// * must update both left and right
// * e.g. if only left is moved, newNumLeft = 0 - (numI + numRight) and that can only be numLeft that's already visited
// * Time Complexity: O(1) because there is no actual operation other than skipping
while(left < nums.length && nums[left] == numLeft) left++;

while(right > left && nums[right] == numRight) right--;
} else if(sum > 0) {
right--;
} else {
left++;
}
}
}

return answers;
}
}
21 changes: 21 additions & 0 deletions climbing-stairs/samcho0608.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
class Solution {
// Problem:
// * can take 1 or 2 steps
// * return: how many distinct ways to climb to the top(n)
// Solution:
// * Time Complexity: O(N)
// * due to memoization(DP)
// * Space Complexity: O(N)
public int climbStairs(int n) {
// memo[i] = distinct steps to reach ith step
int[] memo = new int[n + 1];
memo[0] = 1;
memo[1] = 1;

for(int i = 2; i < n+1; i++) {
memo[i] = memo[i-1] + memo[i-2];
}

return memo[n];
}
}
75 changes: 75 additions & 0 deletions product-of-array-except-self/samcho0608.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
// link: https://leetcode.com/problems/product-of-array-except-self/submissions/1831301674/
// difficulty: Medium
class Solution1 {
// Problem:
// * return: array where answer[i] = product of all elements except nums[i]
// Solution:
// * Time Complexity: O(N)
// * Space Complexity: O(N)
public int[] productExceptSelf(int[] nums) {
int n = nums.length;

// prefixProds[i] = prod of all elements upto i (exclusive)
int[] prefixProds = new int[n];
for(int i = 0; i < n; i++) {
if(i == 0) {
prefixProds[i] = 1;
continue;
}

prefixProds[i] = prefixProds[i-1] * nums[i-1];
}

// suffixProds[i] = prod of all elements from end to i (exclusive)
int[] suffixProds = new int[n];
for(int i = n - 1; i >= 0; i--) {
if(i == n - 1) {
suffixProds[i] = 1;
continue;
}

suffixProds[i] = suffixProds[i+1] * nums[i+1];
}

// multiply prefix and suffix prods to find answers
int[] answers = new int[n];
for(int i = 0; i< n;i++) {
answers[i] = prefixProds[i] * suffixProds[i];
}

return answers;
}
}

// uses only 1 array whereas solution 1 uses 3
class Solution2 {
// Problem:
// * return: array where answer[i] = product of all elements except nums[i]
// Solution:
// * Time Complexity: O(N)
// * Space Complexity: O(N)
public int[] productExceptSelf(int[] nums) {
int n = nums.length;

// prefixProds[i] = prod of all elements upto i (exclusive)
int[] answers = new int[n];
for(int i = 0; i < n; i++) {
if(i == 0) {
answers[i] = 1;
continue;
}

answers[i] = answers[i-1] * nums[i-1];
}

// use a single variable for suffix product
int suffixProd = 1;
for(int i = n - 2; i >= 0; i--) {
suffixProd *= nums[i+1];
answers[i] *= suffixProd;
}

return answers;
}
}

64 changes: 64 additions & 0 deletions valid-anagram/samcho0608.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import java.util.HashMap;

// link: https://leetcode.com/problems/valid-anagram/
// difficulty: Easy
class Solution1 {
// Problem:
// * return: is t an anagram of s
public boolean isAnagram(String s, String t) {
if(s.length() != t.length()) return false;

int n = s.length();

// Space Complexity: O(N)
HashMap<Character, Integer> freqS = new HashMap<>();
HashMap<Character, Integer> freqT = new HashMap<>();

// Time Complexity: O(N)
for(int i = 0; i < n; i++) {
char charS = s.charAt(i);
freqS.put(charS, freqS.getOrDefault(charS, 0) + 1);

char charT = t.charAt(i);
freqT.put(charT, freqT.getOrDefault(charT, 0) + 1);
}

// Time Complexity: O(N)
for(var entryS: freqS.entrySet()) {
int cntT = freqT.getOrDefault(entryS.getKey(), 0);
if(cntT != entryS.getValue()) return false;
}

return true;
}
}

// Map 하나만 사용하는 개선된 방식
class Solution2 {
// Problem:
// * return: is t an anagram of s
public boolean isAnagram(String s, String t) {
if(s.length() != t.length()) return false;

int n = s.length();

// Space Complexity: O(N)
HashMap<Character, Integer> freq = new HashMap<>();

// Time Complexity: O(N)
for(int i = 0; i < n; i++) {
char charS = s.charAt(i);
freq.put(charS, freq.getOrDefault(charS, 0) + 1);

char charT = t.charAt(i);
freq.put(charT, freq.getOrDefault(charT, 0) - 1);
}

// Time Complexity: O(N)
for(int count: freq.values()) {
if(count != 0) return false;
}

return true;
}
}
80 changes: 80 additions & 0 deletions validate-binary-search-tree/samcho0608.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
// link: https://leetcode.com/problems/validate-binary-search-tree/description/
// difficulty: Medium
/**
* 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 Solution1 {
// Problem:
// * return: check if tree is a valid BST
// * left subtree contains keys strictly less than node's key
// * right subtree contains keys strictly greater than node's key
// * recursive structure
// Solution:
// * Time Complexity: O(N)
// * Space Complexity(in terms of call stack):
// * O(N) if skewed
// * O(log N) if not skewed
public boolean isValidBST(TreeNode root) {
// checklist:
// * is subtree a valid bst
// * left subtree : is max value of subtree less than node
// * right subtree : is min value of subtree greater than node
return isValid(root, null, null);
}

private boolean isValid(TreeNode node, Integer min, Integer max) {
if(node == null) return true;

int val = node.val;

if(min != null && val <= min) return false;
if(max != null && val >= max) return false;

if(!isValid(node.left, min, val)) return false;
if(!isValid(node.right, val, max)) return false;

return true;
}
}

// in-order traversal approach
// * reads from left-most to right (strictly increasing val order expected)
class Solution2 {
private Integer prev;

// Solution:
// * Time Complexity: O(N)
// * Space Complexity(in terms of call stack):
// * O(N) if skewed
// * O(log N) if not skewed
public boolean isValidBST(TreeNode root) {
prev = null;
return inorder(root);
}

private boolean inorder(TreeNode node) {
// reached end without failure
if(node == null) return true;

// inorder so travel left first
if(!inorder(node.left)) return false;

// if node value is not greater than prev, it isn't a BST in in-order
if(prev != null && node.val <= prev) return false;
prev = node.val;

return inorder(node.right);
}
}