From 931ef0ffc433fb4bc77819d027d93dde7b61ec9e Mon Sep 17 00:00:00 2001 From: GangBean Date: Wed, 1 Jan 2025 18:31:55 +0900 Subject: [PATCH 1/7] feat: solve merge two sorted lists --- merge-two-sorted-lists/GangBean.java | 73 ++++++++++++++++++++++++++++ 1 file changed, 73 insertions(+) create mode 100644 merge-two-sorted-lists/GangBean.java diff --git a/merge-two-sorted-lists/GangBean.java b/merge-two-sorted-lists/GangBean.java new file mode 100644 index 000000000..60b84752f --- /dev/null +++ b/merge-two-sorted-lists/GangBean.java @@ -0,0 +1,73 @@ +/** + * Definition for singly-linked list. + * public class ListNode { + * int val; + * ListNode next; + * ListNode() {} + * ListNode(int val) { this.val = val; } + * ListNode(int val, ListNode next) { this.val = val; this.next = next; } + * } + */ +class Solution { + public ListNode mergeTwoLists(ListNode list1, ListNode list2) { + /** + 1. understanding + - merge 2 sorted linked list + 2. strategy + - assign return ListNode + - for each node, started in head, compare each node's value, and add smaller value node to return node, and move the node's head to head.next + 3. complexity + - time: O(N + M), N is the length of list1, M is the length of list2 + - space: O(1), exclude the return variable + */ + ListNode curr = null; + ListNode ret = null; + + while (list1 != null && list2 != null) { + if (list1.val < list2.val) { + ListNode node = new ListNode(list1.val); + if (ret == null) { + ret = node; + } else { + curr.next = node; + } + list1 = list1.next; + curr = node; + } else { + ListNode node = new ListNode(list2.val); + if (ret == null) { + ret = node; + } else { + curr.next = node; + } + list2 = list2.next; + curr = node; + } + } + + while (list1 != null) { + ListNode node = new ListNode(list1.val); + if (ret == null) { + ret = node; + } else { + curr.next = node; + } + list1 = list1.next; + curr = node; + } + + while (list2 != null) { + ListNode node = new ListNode(list2.val); + if (ret == null) { + ret = node; + } else { + curr.next = node; + } + list2 = list2.next; + curr = node; + } + + return ret; + } +} + From fd8f57e336eee2023cc322d229780556326b908e Mon Sep 17 00:00:00 2001 From: GangBean Date: Wed, 1 Jan 2025 18:37:02 +0900 Subject: [PATCH 2/7] feat: solve missing number --- missing-number/GangBean.java | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 missing-number/GangBean.java diff --git a/missing-number/GangBean.java b/missing-number/GangBean.java new file mode 100644 index 000000000..bf19c65d8 --- /dev/null +++ b/missing-number/GangBean.java @@ -0,0 +1,19 @@ +class Solution { + public int missingNumber(int[] nums) { + /** + 1. understanding + - array nums, n distinct numbers in range [0, n] + - find missing number + 2. strategy + - you can calculate the sum of range [0, n]: n(n+1)/2 ... (1) + - and the sum of nums ... (2) + - and then extract (2) from (1) = (missing value) what we want. + 3. complexity + - time: O(N), N is the length of nums + - space: O(1) + */ + int N = nums.length; + return N*(N+1)/2 - Arrays.stream(nums).sum(); + } +} + From 611a7167f040253e2aa1621f2ebb900afa93be8d Mon Sep 17 00:00:00 2001 From: GangBean Date: Wed, 1 Jan 2025 19:03:03 +0900 Subject: [PATCH 3/7] feat: solve word search --- word-search/GangBean.java | 51 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 word-search/GangBean.java diff --git a/word-search/GangBean.java b/word-search/GangBean.java new file mode 100644 index 000000000..ecf3bf47b --- /dev/null +++ b/word-search/GangBean.java @@ -0,0 +1,51 @@ +class Solution { + int[] dx = {0, 1, 0, -1}; + int[] dy = {1, 0, -1, 0}; + public boolean exist(char[][] board, String word) { + /** + 1. understanding + - check if word can be constructed from board, + - start in any block, moving only 4 direction, up, left, below, right + - can't use same block + 2. strategy + - backtracking and dfs + - iterate over each block, if first character matches, find words in depth first search algorithm + - each dfs, mark current block is visited, and find 4 or less possible directions, when any character matches with next character in word, then call dfs in that block recursively + 3. complexity + - time: O(M * N * L), where L is the length of word + - space: O(M * N) which marks if block of the indices is visited or not + */ + boolean[][] isVisited = new boolean[board.length][board[0].length]; + boolean ret = false; + for (int y = 0; y < board.length; y++) { + for (int x = 0; x < board[0].length; x++) { + if (board[y][x] == word.charAt(0)) { + isVisited[y][x] = true; + ret = ret || isWordExists(board, isVisited, word, y, x, 0); + isVisited[y][x] = false; + } + } + } + return ret; + } + + private boolean isWordExists(char[][] board, boolean[][] isVisited, String word, int y, int x, int idx) { + if (idx == word.length() - 1) return true; + // System.out.println(String.format("(%d, %d): %s", y, x, word.charAt(idx))); + boolean isExists = false; + for (int dir = 0; dir < 4; dir++) { + int ny = y + dy[dir]; + int nx = x + dx[dir]; + if (0 <= ny && ny < board.length + && 0 <= nx && nx < board[0].length + && !isVisited[ny][nx] + && word.charAt(idx + 1) == board[ny][nx]) { + isVisited[ny][nx] = true; + isExists = isExists || isWordExists(board, isVisited, word, ny, nx, idx + 1); + isVisited[ny][nx] = false; + } + } + return isExists; + } +} + From 3336965af2490941283134cd5e5511b5e03b1f88 Mon Sep 17 00:00:00 2001 From: GangBean Date: Wed, 1 Jan 2025 19:10:31 +0900 Subject: [PATCH 4/7] feat: solve palindromic substrings --- palindromic-substrings/GangBean.java | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/palindromic-substrings/GangBean.java b/palindromic-substrings/GangBean.java index ebb22ac35..d690efd01 100644 --- a/palindromic-substrings/GangBean.java +++ b/palindromic-substrings/GangBean.java @@ -1,8 +1,15 @@ class Solution { public int countSubstrings(String s) { /** - 각 문자를 중간으로 갖는 palindrome 여부 체크 - + 두개의 문자를 중간으로 갖는 palindrome 여부 체크 + 1. understanding + - find the number of palindromic substrings + 2. strategy + - iterate over each character, count below substrings + - First, start with same position, move left and right directions each, until two charactes are not same. + - Second, start with i and i + 1 position, move left and right directions until two chracters are not same. + 3. complexity + - time: O(N^2) + - space: O(1) */ int count = 0; int length = s.length(); @@ -27,3 +34,4 @@ public int countSubstrings(String s) { return count; // O(N^2) } } + From 2f88c69b4f115b6d87beab1bf2f37d8b740085a6 Mon Sep 17 00:00:00 2001 From: GangBean Date: Thu, 2 Jan 2025 19:47:40 +0900 Subject: [PATCH 5/7] feat: solve coin change --- coin-change/GangBean.java | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 coin-change/GangBean.java diff --git a/coin-change/GangBean.java b/coin-change/GangBean.java new file mode 100644 index 000000000..4a19f8ce8 --- /dev/null +++ b/coin-change/GangBean.java @@ -0,0 +1,32 @@ +class Solution { + public int coinChange(int[] coins, int amount) { + /** + 1. understanding + - given coins that can be used, find the minimum count of coins sum up to input amount value. + - [1,2,5]: 11 + - 2 * 5 + 1 * 1: 3 -> use high value coin as much as possible if the remain can be sumed up by remain coins. + 2. strategy + - If you search in greedy way, it will takes over O(min(amount/coin) ^ N), given N is the length of coins. + - Let dp[k] is the number of coins which are sum up to amount k, in a given coin set. + - Then, dp[k] = min(dp[k], dp[k-coin] + 1) + 3. complexity + - time: O(CA), where C is the length of coins, A is amount value + - space: O(A), where A is amount value + */ + Arrays.sort(coins); + + int[] dp = new int[amount + 1]; + for (int i = 1; i <= amount; i++) { + dp[i] = amount + 1; + } + + for (int coin: coins) { // O(C) + for (int k = coin; k <= amount; k++) { // O(A) + dp[k] = Math.min(dp[k], dp[k-coin] + 1); + } + } + + return (dp[amount] >= amount + 1) ? -1 : dp[amount]; + } +} + From 9c6b6845b3e1afee375bfe082c069eb2c590b609 Mon Sep 17 00:00:00 2001 From: GangBean Date: Sat, 4 Jan 2025 12:16:38 +0900 Subject: [PATCH 6/7] refactor: remove duplicate code in word search --- word-search/GangBean.java | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/word-search/GangBean.java b/word-search/GangBean.java index ecf3bf47b..5901ea044 100644 --- a/word-search/GangBean.java +++ b/word-search/GangBean.java @@ -16,23 +16,19 @@ public boolean exist(char[][] board, String word) { - space: O(M * N) which marks if block of the indices is visited or not */ boolean[][] isVisited = new boolean[board.length][board[0].length]; - boolean ret = false; for (int y = 0; y < board.length; y++) { for (int x = 0; x < board[0].length; x++) { - if (board[y][x] == word.charAt(0)) { - isVisited[y][x] = true; - ret = ret || isWordExists(board, isVisited, word, y, x, 0); - isVisited[y][x] = false; - } + if (isWordExists(board, isVisited, word, y, x, 0)) return true; } } - return ret; + return false; } private boolean isWordExists(char[][] board, boolean[][] isVisited, String word, int y, int x, int idx) { + if (board[y][x] != word.charAt(idx)) return false; if (idx == word.length() - 1) return true; - // System.out.println(String.format("(%d, %d): %s", y, x, word.charAt(idx))); - boolean isExists = false; + // boolean isExists = false; + isVisited[y][x] = true; for (int dir = 0; dir < 4; dir++) { int ny = y + dy[dir]; int nx = x + dx[dir]; @@ -41,11 +37,12 @@ private boolean isWordExists(char[][] board, boolean[][] isVisited, String word, && !isVisited[ny][nx] && word.charAt(idx + 1) == board[ny][nx]) { isVisited[ny][nx] = true; - isExists = isExists || isWordExists(board, isVisited, word, ny, nx, idx + 1); + if (isWordExists(board, isVisited, word, ny, nx, idx + 1)) return true; isVisited[ny][nx] = false; } } - return isExists; + isVisited[y][x] = false; + return false; } } From e9cabee017992de84d83c121812e19d58267772d Mon Sep 17 00:00:00 2001 From: GangBean Date: Sat, 4 Jan 2025 12:17:58 +0900 Subject: [PATCH 7/7] refactor: remove coins sorting --- coin-change/GangBean.java | 1 - 1 file changed, 1 deletion(-) diff --git a/coin-change/GangBean.java b/coin-change/GangBean.java index 4a19f8ce8..635f9e8d4 100644 --- a/coin-change/GangBean.java +++ b/coin-change/GangBean.java @@ -13,7 +13,6 @@ public int coinChange(int[] coins, int amount) { - time: O(CA), where C is the length of coins, A is amount value - space: O(A), where A is amount value */ - Arrays.sort(coins); int[] dp = new int[amount + 1]; for (int i = 1; i <= amount; i++) {