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
55 changes: 55 additions & 0 deletions 3sum/dohyeon2.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import java.util.Arrays;
import java.util.ArrayList;
import java.util.List;

class Solution {
// TC: O(n^2)
// SC: O(n^2)
public List<List<Integer>> threeSum(int[] nums) {
List<List<Integer>> answer = new ArrayList<List<Integer>>();

// Sort the array to use two-pointer technique.
Arrays.sort(nums);

// Exclude the last two elements from the loop
// since the two pointers are involved in the iteration.
for (int i = 0; i < nums.length - 2; i++) {
if (i - 1 >= 0 && nums[i] == nums[i - 1]) {
// Skip if this number is the same as the previous one,
// so that we can avoid duplicate triplets.
continue;
}

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

while (left < right) {
int sum = nums[i] + nums[left] + nums[right];
if (sum == 0) {
ArrayList<Integer> list = new ArrayList<>(
Arrays.asList(nums[i], nums[left], nums[right]));
answer.add(list);

// According to the problem, we need to avoid duplicate triplets.
// Therefore, this loop is needed.
while (left < right && nums[left] == nums[left + 1]) {
left++;
}
while (left < right && nums[right] == nums[right - 1]) {
right--;
}

left++;
right--;
} else if (sum < 0) {
left++;
} else {
right--;
}
}

}

return answer;
}
}
32 changes: 32 additions & 0 deletions climbing-stairs/dohyeon2.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
class Solution {
// TC: O(n)
// SC: O(1)
public int climbStairs(int n) {
if (n < 3) {
// If n is less than 3 there are n ways.
return n;
}

// There is one way to reach the first stair.
int nMinus2 = 1;
// There are two ways to reach the second stair.
int nMinus1 = 2;

int nZero = nMinus1 + nMinus2;

for (int step = 3; step <= n; step++) {
// To reach the third stair, it must come from the first stair or the second
// stair.
// The number of ways to reach the nth stair is the sum of those of the (n-1)th
// stair and those of the (n-2)th stair.
nZero = nMinus1 + nMinus2;

nMinus2 = nMinus1;
nMinus1 = nZero;
}

// A separate variable name is used to distinguish between nZero and nMinus1 so
// that the nth value is explicit
return nZero;
}
}
49 changes: 49 additions & 0 deletions product-of-array-except-self/dohyeon2.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import java.util.Arrays;

class Solution {
// TC : O(n)
// SC : O(n)
public int[] productExceptSelf(int[] nums) {
/**
* I previously solved this problem using division,
* but the problem restricts that approach.
* This was pointed out in the following comment:
* https://github.com/DaleStudy/leetcode-study/pull/2396#discussion_r2934545648
*
* Approach:
* Compute prefix products using left[i-1] * nums[i-1],
* which represents the product of elements before i.
*
* Compute suffix products using right[i+1] * nums[i+1]
* by traversing from right to left.
*
* The result at index i is:
* left[i] * right[i]
*/

int[] answer = new int[nums.length];

int[] left = new int[nums.length];
Arrays.fill(left, 1);
int[] right = new int[nums.length];
Arrays.fill(right, 1);

for (int i = 0; i < nums.length; i++) {
if (i - 1 < 0)
continue;
left[i] *= left[i - 1] * nums[i - 1];
}

for (int i = nums.length - 1; i >= 0; i--) {
if (i + 1 > nums.length - 1)
continue;
right[i] *= right[i + 1] * nums[i + 1];
}

for (int i = 0; i < nums.length; i++) {
answer[i] = left[i] * right[i];
}

return answer;
}
}
26 changes: 26 additions & 0 deletions valid-anagram/dohyeon2.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import java.util.HashMap;

class Solution {
public boolean isAnagram(String s, String t) {
if (s.length() != t.length()) {
return false;
}

// TC = O(n)
// SC = O(n)
HashMap<Character, Integer> sMap = new HashMap<>();

for (char c : s.toCharArray()) {
sMap.merge(c, 1, Integer::sum);
}

for (char c : t.toCharArray()) {
if (sMap.getOrDefault(c, 0) == 0) {
return false;
}
sMap.merge(c, -1, Integer::sum);
}

return true;
}
}
52 changes: 52 additions & 0 deletions validate-binary-search-tree/dohyeon2.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
/**
* 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 {
// TC : O(n) Each node is visited once in the loop.
// SC : O(n) Memory allocated for call stack
// In the first attempt, I tried BFS to solve the problem.
// But I figured out that I needed to validate a BST recursively.
// So, I switched to DFS to solve the problem.
// At first, I compared the node's value with the children's values.
// And I checked that those values were in the range of min and max.
// Then, I simplified the approach by
// comparing the node's value with the min and max values (assisted by ChatGPT).
public boolean isValidBST(TreeNode root) {
return dfs(root);
}

// Overloading the method to set default arguments
private boolean dfs(TreeNode node) {
return dfs(node, Long.MIN_VALUE, Long.MAX_VALUE);
}

private boolean dfs(TreeNode node, long min, long max) {
// It's the end of the tree, return true,
// because the search is valid until this point.
if (node == null) {
return true;
}

if (node.val <= min) {
return false;
}
if (node.val >= max) {
return false;
}

// All the result of search must be true, if the tree is valid
return dfs(node.left, min, node.val) && dfs(node.right, node.val, max);
}
}
Loading