From bd19c4842e7d0552bad0c7efd0fe24f5dd635ca7 Mon Sep 17 00:00:00 2001 From: ekgns33 Date: Tue, 14 Jan 2025 16:51:02 +0900 Subject: [PATCH 1/5] feat : valid-parentheses --- valid-parentheses/ekgns33.java | 54 ++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) create mode 100644 valid-parentheses/ekgns33.java diff --git a/valid-parentheses/ekgns33.java b/valid-parentheses/ekgns33.java new file mode 100644 index 000000000..f5167060d --- /dev/null +++ b/valid-parentheses/ekgns33.java @@ -0,0 +1,54 @@ +/** + input : string s contains just (, ), {, }, [, ] + output : return if s is valid + valid means that parentheses are matched(balanced) + example + ((())) : valid + (((())) : invalid + {() : invalid + + constraint : + 1) input string can be empty string? + nope. at least one character >> if length is odd number return false + edge: + 1) if the length of string is odd number return false + + solution 1) + ds : stack + algo : x + iterate through the string s + if opening bracket, add to stack + else check the top element of stack + if matched pop + else return false; + return false + + tc : O(n) + sc : O(n) worst case : every character is opening bracket + + */ +class Solution { + public boolean isValid(String s) { + //edge + if(s.length() % 2 == 1) return false; + // we can use deque instead + Stack stack = new Stack<>(); + + for(char c : s.toCharArray()) { + if(c == '(' || c == '{' || c == '[') { + stack.push(c); + } else { + if(stack.isEmpty()) return false; + if(c == ')') { + if(stack.peek() != '(') return false; + } else if (c == '}') { + if(stack.peek() != '{') return false; + } else if (c == ']'){ + if(stack.peek() != '[') return false; + } + stack.pop(); + } + } + return stack.isEmpty(); + } +} From 954ec01894b5a1f2cbc35aa2d24b4bec7f5d4527 Mon Sep 17 00:00:00 2001 From: ekgns33 Date: Tue, 14 Jan 2025 17:09:47 +0900 Subject: [PATCH 2/5] feat : container-with-most-water --- container-with-most-water/ekgns33.java | 83 ++++++++++++++++++++++++++ 1 file changed, 83 insertions(+) create mode 100644 container-with-most-water/ekgns33.java diff --git a/container-with-most-water/ekgns33.java b/container-with-most-water/ekgns33.java new file mode 100644 index 000000000..65217990b --- /dev/null +++ b/container-with-most-water/ekgns33.java @@ -0,0 +1,83 @@ +/* +input : array of integer height +output : maximum amount of water a container can store. + +we can build container with two different line (height[i], height[j] when i < j) + +example +1 8 6 2 5 4 8 3 7 +choose i = 1. +choose j = 4 + 8 ______5 + amount of water == (j - i) * min(height[i], height[j]) + = 3 * 5 = 15 + +we have to maximize amount of water. + +constraints: +1) is the input array valid? +length of array is in range [2, 10^5] +2) positive integers? +no. range of height is [0, 10 ^4] +>> check amount can be overflow. 10^4 * 10 ^ 5 = 10^9 < Integer range +edge: +1) if length is 2 +return min(height[0], height[1]). +... + +solution 1) brute force; +iterate through the array from index i = 0 to n-1 + when n is the length of input array + iterate through the array from index j = i + 1 to n; + calculate the amount of water and update max amount +ds : array +algo : x +tc : O(n^2) ~= 10^10 TLE +space : O(1) + +solution 2) better +ds : array +algo: two pointer? + +two variant for calculating amount of water +1. height 2. width + +set width maximum at first, check heights + decrease width one by one + + - at each step width is maximum. + so we have to maximize + the minimum between left and right pointer + +use left and right pointer +while left < right + + calculate amount + compare + if height[left] < height[right] + move left by one + else + vice versa + +return max +tc : O(n) +sc : O(1) + + */ +class Solution { + public int maxArea(int[] height) { + int left = 0; + int right = height.length - 1; + int maxAmount = 0; + while(left < right) { + int curAmount = (right - left) * Math.min(height[left], height[right]); + maxAmount = Math.max(maxAmount, curAmount); + if(height[left] < height[right]) { + left++; + } else { + right--; + } + } + return maxAmount; + } +} From ac9ae5185ed6f0a1c1c9ec2156ab3329039342b1 Mon Sep 17 00:00:00 2001 From: ekgns33 Date: Tue, 14 Jan 2025 18:14:14 +0900 Subject: [PATCH 3/5] feat : word-dictionary --- .../ekgns33.java | 109 ++++++++++++++++++ 1 file changed, 109 insertions(+) create mode 100644 design-add-and-search-words-data-structure/ekgns33.java diff --git a/design-add-and-search-words-data-structure/ekgns33.java b/design-add-and-search-words-data-structure/ekgns33.java new file mode 100644 index 000000000..9757da997 --- /dev/null +++ b/design-add-and-search-words-data-structure/ekgns33.java @@ -0,0 +1,109 @@ +/** + design ds that supports add, find + find if string matches any previously added string. + >> some kind of dictionary + + example + add bad + add dad + add mad + search pad >> false + search bad >> true + search .ad >> true . can be 'b' or 'd' or 'm' + search b.. >> true .. can be "ad" + + constraints: + 1) empty string can be valid input? + nope. lenght of string is in range of [1, 25] + 2) string only contiains alphanumeric? or alphabet + only lowercase English letters + 3) how many queries can be given as input? + at most 10^4 + + solution 1) brute force + save to data structure. for add + check every character for all the saved words + O(kn) when k is the number of saved words, + n is the length of input word token + 25 * 25 * 10^4 + tc : O(kn) + O(kn) + add : O(1) + search : O(kn) + sc : O(kn) + + solution 2) trie? + + save words to trie. + when searching + do bfs or backtracking dfs + if current charcter is . add all childs + else add matching childs + overall tc : O(sum(m)) + O(n), + add : O(m), when m is the length of saved word + search : O(n), when n is the length of searh word + sc : O(sum(m)) + + if volume of search query is much bigger than add query + trie solution would be better + O(n) search time vs O(mn) search time + */ +class WordDictionary { + class TrieNode { + TrieNode[] childs; + boolean isEnd; + TrieNode() { + childs = new TrieNode[26]; + isEnd = false; + } + } + TrieNode root; + public WordDictionary() { + root = new TrieNode(); + } + + public void addWord(String word) { + TrieNode curNode = root; + for(char c : word.toCharArray()) { + if(curNode.childs[c-'a'] == null) { + curNode.childs[c-'a'] = new TrieNode(); + } + curNode = curNode.childs[c-'a']; + } + curNode.isEnd = true; + } + + public boolean search(String word) { + return dfsHelper(root, word, 0); + } + + public boolean dfsHelper(TrieNode node, String word, int p) { + //end clause + if(p == word.length()) { + return node.isEnd; + } + + char curC = word.charAt(p); + if(curC == '.') { + for(TrieNode next : node.childs) { + if(next != null) { + if(dfsHelper(next, word, p + 1)) return true; + } + } + return false; + } else { + if(node.childs[curC-'a'] != null) { + if(dfsHelper(node.childs[curC - 'a'], word, p + 1)) return true; + } + return false; + } + + + } +} + +/** + * Your WordDictionary object will be instantiated and called as such: + * WordDictionary obj = new WordDictionary(); + * obj.addWord(word); + * boolean param_2 = obj.search(word); + */ From 057821ee5829c4d541e49c4903006fa593519441 Mon Sep 17 00:00:00 2001 From: ekgns33 Date: Fri, 17 Jan 2025 15:31:51 +0900 Subject: [PATCH 4/5] feat : spiral-matrix --- spiral-matrix/ekgns33.java | 42 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 spiral-matrix/ekgns33.java diff --git a/spiral-matrix/ekgns33.java b/spiral-matrix/ekgns33.java new file mode 100644 index 000000000..e501cac40 --- /dev/null +++ b/spiral-matrix/ekgns33.java @@ -0,0 +1,42 @@ +/* +*. lr -> +* ^ 1 2 3 4. rd +* lu 5 6 7 8. v +* <- rl +* tc : O(mn) +* sc : O(1) +* */ + +class Solution { + public List spiralOrder(int[][] matrix) { + int m = matrix.length; + int n = matrix[0].length; + int lr = 0, rd = 0, rl = n -1, lu = m - 1; + int cnt = 0, target = m*n; + List res = new ArrayList<>(); + + while(lr <= rl && rd <= lu) { + for(int startLeft = lr; startLeft <= rl; startLeft++) { + res.add(matrix[rd][startLeft]); + } + rd++; + for(int startUp = rd; startUp <=lu; startUp++) { + res.add(matrix[startUp][rl]); + } + rl--; + if(rd <= lu) { + for(int startRight = rl; startRight >= lr; startRight--) { + res.add(matrix[lu][startRight]); + } + } + lu--; + if(lr <= rl) { + for(int startDown = lu; startDown >= rd; startDown--) { + res.add(matrix[startDown][lr]); + } + } + lr++; + } + return res; + } +} From c636ff21239520ace7240c756562d40049c00354 Mon Sep 17 00:00:00 2001 From: ekgns33 Date: Fri, 17 Jan 2025 15:32:00 +0900 Subject: [PATCH 5/5] feat : lis --- longest-increasing-subsequence/ekgns33.java | 60 +++++++++++++++++++++ 1 file changed, 60 insertions(+) create mode 100644 longest-increasing-subsequence/ekgns33.java diff --git a/longest-increasing-subsequence/ekgns33.java b/longest-increasing-subsequence/ekgns33.java new file mode 100644 index 000000000..2a0f7e0bc --- /dev/null +++ b/longest-increasing-subsequence/ekgns33.java @@ -0,0 +1,60 @@ +/** + input : array of integers + output : length of the longest strictly increasing subsequence; + example + 0 1 0 3 2 3 > 0 1 2 3 >> length : 4 + 4 3 2 1 > 1 >> length : 1 + 1 1 1 1 > 1 >> length : 1 + + constraints : + 1) empty array allowed? + no, at least one + + solution 1) brute force + nested for loop + iterate through the array from index i = 0 to n-1 when n is the lenght of input + iterate throught the array from index j = i + 1 to n + update current Maximum value + if bigger than prev max value count ++ + tc : O(n^2); + sc : O(1) + + solution 2) binary search + dp + iterate through the array + search from saved values. + if current value is bigger than everything add + else change value + + let val[i] save the smallest value of length i subsequence + tc : O(nlogn) + sc : O(n) + + */ + +class Solution { + public int lengthOfLIS(int[] nums) { + List vals = new ArrayList<>(); + for(int num : nums) { + if(vals.isEmpty() || vals.getLast() < num) { + vals.add(num); + } else { + vals.set(binarySearch(vals, num), num); + } + } + return vals.size(); + } + int binarySearch(List vals, int num) { + int l = 0, r = vals.size()-1; + while(l <= r) { + int mid = (r - l) / 2+ l; + if(vals.get(mid) == num) { + return mid; + } else if (vals.get(mid) > num) { + r = mid - 1; + } else { + l = mid + 1; + } + } + return l; + } +}