From 0d5b4344f2295865365f8408c795970059cb10a0 Mon Sep 17 00:00:00 2001 From: "Yongseok.choi" Date: Sat, 3 May 2025 10:57:45 +0900 Subject: [PATCH 1/6] add: Valid Parentheses --- valid-parentheses/YoungSeok-Choi.java | 33 +++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 valid-parentheses/YoungSeok-Choi.java diff --git a/valid-parentheses/YoungSeok-Choi.java b/valid-parentheses/YoungSeok-Choi.java new file mode 100644 index 000000000..1d756e278 --- /dev/null +++ b/valid-parentheses/YoungSeok-Choi.java @@ -0,0 +1,33 @@ +import java.util.Stack; + +// TC: O(n) +class Solution { + Stack st = new Stack<>(); + public boolean isValid(String s) { + for(char c : s.toCharArray()) { + if(st.empty() || !isClosing(c)) { + st.push(c); + continue; + } + + char temp = st.peek(); + if(temp == '(' && c == ')') { + st.pop(); + } else if(temp == '[' && c == ']') { + st.pop(); + } else if(temp == '{' && c == '}') { + st.pop(); + } else { + st.push(c); + } + } + + return st.empty(); + } + + public boolean isClosing(char c) { + if(c == ')' || c == ']' || c == '}') return true; + + return false; + } +} From b4b8026b451f9bfd2fa866755cd2773a6b65773e Mon Sep 17 00:00:00 2001 From: "Yongseok.choi" Date: Mon, 5 May 2025 18:40:47 +0900 Subject: [PATCH 2/6] =?UTF-8?q?add:=20=20=EC=A6=9D=EA=B0=80=ED=95=98?= =?UTF-8?q?=EB=8A=94=20=EC=B5=9C=EB=8C=80=20=EB=B6=80=EB=B6=84=EC=88=98?= =?UTF-8?q?=EC=97=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../YoungSeok-Choi.java | 69 +++++++++++++++++++ 1 file changed, 69 insertions(+) create mode 100644 longest-increasing-subsequence/YoungSeok-Choi.java diff --git a/longest-increasing-subsequence/YoungSeok-Choi.java b/longest-increasing-subsequence/YoungSeok-Choi.java new file mode 100644 index 000000000..e894d02c5 --- /dev/null +++ b/longest-increasing-subsequence/YoungSeok-Choi.java @@ -0,0 +1,69 @@ +import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; + +// tc: O(n) +// idea: max largest subseq length for "N" th array index +class Solution { + + public int lengthOfLIS(int[] nums) { + + int[] arr = new int[nums.length]; + Arrays.fill(arr, 1); + + for(int i = 1; i < nums.length; i++) { + for(int j = 0; j < i; j++) { + if(nums[j] < nums[i]) { + arr[i] = Math.max(arr[i], arr[j] + 1); + } + } + } + + int mx = -987654321; + for(int anInt : arr) { + System.out.print(anInt + " "); + mx = Math.max(mx, anInt); + } + + return mx; + } +} + +// time limit exceed + +class WrongSolution { + + public boolean[] visit; + public int mxVal = -987654321; + public int mx = 1; + public Map m = new HashMap<>(); + + public int lengthOfLIS(int[] nums) { + for(int i = 0; i < nums.length; i++) { + m = new HashMap<>(); + mxVal = Math.max(mxVal, nums[i]); + m.put(nums[i], true); + dfs(i, nums); + mxVal = -987654321; + } + + return mx; + } + + public void dfs(int idx, int[] nums) { + mx = Math.max(mx, m.size()); + + for(int i = idx + 1; i < nums.length; i++) { + if(mxVal < nums[i]) { + int prev = mxVal; + mxVal = nums[i]; + m.put(nums[i], true); + + dfs(i, nums); + + mxVal = prev; + m.remove(nums[i]); + } + } + } +} From ff8a468e948b6bbf128a5c7bf92c6bab9231ef79 Mon Sep 17 00:00:00 2001 From: "Yongseok.choi" Date: Mon, 5 May 2025 20:00:34 +0900 Subject: [PATCH 3/6] =?UTF-8?q?add:=20=EB=AC=BC=EB=8B=B4=EA=B8=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- container-with-most-water/YoungSeok-Choi.java | 63 +++++++++++++++++++ 1 file changed, 63 insertions(+) create mode 100644 container-with-most-water/YoungSeok-Choi.java diff --git a/container-with-most-water/YoungSeok-Choi.java b/container-with-most-water/YoungSeok-Choi.java new file mode 100644 index 000000000..bce1c0316 --- /dev/null +++ b/container-with-most-water/YoungSeok-Choi.java @@ -0,0 +1,63 @@ +// tc: O(n) +// 투 포인터라는 문제풀이 방법으로 간단히 (답지보고) 해결... +class Solution { + public int maxArea(int[] h) { + int start = 0; + int end = h.length - 1; + int mx = -987654321; + + while(start < end) { + mx = Math.max(mx, (end - start) * Math.min(h[start], h[end])); + + if(h[start] < h[end]) { + start++; + } else { + end--; + } + } + + return mx; + } +} + + +// 예외처리가 덕지덕지 붙기 시작할 때. (잘못됨을 깨닫고)다른 방법으로 풀어햐 하는건 아닌지 생각하는 습관 필요함..ㅠ +class WrongSolution { + public int maxArea(int[] h) { + int mx = Math.min(h[0], h[1]); + int idx = 0; + + for(int i = 1; i < h.length; i++) { + int offset = i - idx; + + int prevCalc = Math.min(h[i - 1], h[i]); + int calc = Math.min(h[idx], h[i]); + int newMx = calc * offset; + + // 새롭게 인덱스를 바꿔버리는게 더 나을때. + if(prevCalc > newMx) { + idx = i - 1; + mx = Math.max(mx, prevCalc); + continue; + } + + // 물을 더 많이 담을 수 있을 때. + if(h[idx] < h[i] && newMx > mx) { + if(i == 2) { + int exc = Math.min(h[1], h[i]) * offset; + if(exc > newMx) { + idx = 1; + mx = Math.max(exc, mx); + continue; + } + } + + idx = i; + } + + mx = Math.max(newMx, mx); + } + + return mx; + } +} From 98a55c0e29287370263a0ad651e21e8b4ed80efb Mon Sep 17 00:00:00 2001 From: "Yongseok.choi" Date: Thu, 8 May 2025 07:06:45 +0900 Subject: [PATCH 4/6] =?UTF-8?q?add:=20=EB=82=98=EC=84=A0=20=EB=B0=B0?= =?UTF-8?q?=EC=97=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- spiral-matrix/YoungSeok-Choi.java | 55 +++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 spiral-matrix/YoungSeok-Choi.java diff --git a/spiral-matrix/YoungSeok-Choi.java b/spiral-matrix/YoungSeok-Choi.java new file mode 100644 index 000000000..7f4d4853d --- /dev/null +++ b/spiral-matrix/YoungSeok-Choi.java @@ -0,0 +1,55 @@ +import java.util.ArrayList; +import java.util.List; + +class Solution { + public List res = new ArrayList<>(); + public boolean[][] visit; + + public List spiralOrder(int[][] m) { + int min = Math.min(m.length, m[0].length); + int w = m.length; + int h = m[0].length; + + visit = new boolean[w][h]; + + for(int i = 0; i < (min / 2) + 1; i++) { + spiralDepth(i, m); + } + + return res; + } + + public void spiralDepth(int d, int[][] m) { + int w = m[0].length; + int h = m.length; + + for(int i = d; i < (w - d); i++) { + visit(d, i, m); + } + + for (int i = d + 1; i < h - d; i++) { + visit(i, w - d - 1, m); + } + + // NOTE: 우측하단 에서 왼쪽으로 이동하거나, 좌하단에서 위로 이동할 때 가로(혹은 세로)가 1일때 방어하는 로직 + if ((h - d - 1) != d) { + // 우상단 에서 아래로 내려오면서 우 하단 구석 인덱스는 출력했기 때문에 - 2를 뺴주고, 왼쪽의 끝까지 출력해야하기 때문에 >= 연산을 사용해 for 반복횟수결정 + for (int i = w - d - 2; i >= d; i--) { + visit(h - d - 1, i, m); + } + } + + if ((w - d - 1) != d) { + for (int i = h - d - 2; i > d; i--) { + visit(i, d, m); + } + } + } + + public void visit(int x, int y, int[][] m) { + if(!visit[x][y]) { + visit[x][y] = true; + res.add(m[x][y]); + } + } +} From 51256afed45794909e67ff37b615f7de6dc7c5fe Mon Sep 17 00:00:00 2001 From: "Yongseok.choi" Date: Thu, 8 May 2025 07:16:29 +0900 Subject: [PATCH 5/6] =?UTF-8?q?add:=20prefix=20tire=20=EA=B0=9C=EC=84=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../YoungSeok-Choi.java | 82 ++++++++++++++++--- 1 file changed, 72 insertions(+), 10 deletions(-) diff --git a/implement-trie-prefix-tree/YoungSeok-Choi.java b/implement-trie-prefix-tree/YoungSeok-Choi.java index 54e2dfcc9..775f28d98 100644 --- a/implement-trie-prefix-tree/YoungSeok-Choi.java +++ b/implement-trie-prefix-tree/YoungSeok-Choi.java @@ -1,30 +1,63 @@ import java.util.HashMap; import java.util.Map; -// Map으로 풀려버려서 당황.. -// 이진트리? 어떤식으로 풀어야 할지 자료구조 정하고 다시 풀어보기.. +// 한 글자씩 잘라서 하위 자식 노드들로 관리 +// search 동작은 기존 그대로 Map자료구조에서 찾고, 이후 prefix연산에서 속도를 개선 (230ms -> 30ms) class Trie { - Map tMap; + private Trie[] child; + private Character val; + private Map cMap; public Trie() { - this.tMap = new HashMap<>(); + this.cMap = new HashMap<>(); + this.val = null; } public void insert(String word) { - this.tMap.put(word, true); + if(this.cMap.containsKey(word)) return; + + this.cMap.put(word, true); + this.innerInsert(word); + } + + public void innerInsert(String word) { + if(word.length() == 0) return; + + if(this.child == null) { + this.child = new Trie[26]; + } + + char c = word.charAt(0); + int idx = c - 97; + + if(this.child[idx] == null) { + this.child[idx] = new Trie(); + this.child[idx].val = c; + } + + this.child[idx].innerInsert(word.substring(1)); } public boolean search(String word) { - return this.tMap.containsKey(word); + return this.cMap.containsKey(word); } + + // public boolean search(String word) { + + // } - public boolean startsWith(String prefix) { - for(String key : this.tMap.keySet()) { - if(key.startsWith(prefix)) return true; + public boolean startsWith(String word) { + if(word.length() == 0) { + return true; } - return false; + char c = word.charAt(0); + int idx = c - 97; + if(this.child == null || this.child[idx] == null || this.child[idx].val == null) return false; + + + return this.child[idx].startsWith(word.substring(1)); } } @@ -35,3 +68,32 @@ public boolean startsWith(String prefix) { * boolean param_2 = obj.search(word); * boolean param_3 = obj.startsWith(prefix); */ + + + // Map으로 풀려버려서 당황.. +// 이진트리? 어떤식으로 풀어야 할지 자료구조 정하고 다시 풀어보기.. +class BeforeTrie { + + Map tMap; + + public BeforeTrie() { + this.tMap = new HashMap<>(); + } + + public void insert(String word) { + this.tMap.put(word, true); + } + + public boolean search(String word) { + return this.tMap.containsKey(word); + } + + public boolean startsWith(String prefix) { + for(String key : this.tMap.keySet()) { + if(key.startsWith(prefix)) return true; + } + + return false; + } +} + From ae1297196bb72e079020a912493e85e2f4e9f853 Mon Sep 17 00:00:00 2001 From: "Yongseok.choi" Date: Thu, 8 May 2025 08:17:14 +0900 Subject: [PATCH 6/6] =?UTF-8?q?add:=20=EB=AC=B8=EC=9E=90=EC=82=AC=EC=A0=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../YoungSeok-Choi.java | 170 ++++++++++++++++++ 1 file changed, 170 insertions(+) create mode 100644 design-add-and-search-words-data-structure/YoungSeok-Choi.java diff --git a/design-add-and-search-words-data-structure/YoungSeok-Choi.java b/design-add-and-search-words-data-structure/YoungSeok-Choi.java new file mode 100644 index 000000000..14644630c --- /dev/null +++ b/design-add-and-search-words-data-structure/YoungSeok-Choi.java @@ -0,0 +1,170 @@ +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + + +// NOTE: dot에 대한 wildcard 검색이 핵심이었던 문제. +// NOTE: tc -> 문자 입력 O(n), 패턴검색 O(26^n), 패턴X검색 O(1) + +/** + 검색어 | 의미 + "." | 길이가 1인 아무 문자와 매치 + ".a" | 길이 2: 첫 글자는 아무 문자, 두 번째는 a + "..d" | 길이 3: 처음 두 글자는 아무 문자, 마지막은 d + "..." | 길이 3인 모든 단어와 매치 +*/ +class WordDictionary { + + private WordDictionary[] child; + private Character val; + private Map cMap; + + public WordDictionary() { + this.cMap = new HashMap<>(); + this.val = null; + } + + public void addWord(String word) { + if(this.cMap.containsKey(word)) return; + + this.cMap.put(word, true); + this.innerInsert(word); + } + + public void innerInsert(String word) { + if(word.length() == 0) return; + + if(this.child == null) { + this.child = new WordDictionary[26]; + } + + char c = word.charAt(0); + int idx = c - 97; + + if(this.child[idx] == null) { + this.child[idx] = new WordDictionary(); + this.child[idx].val = c; + } + + this.child[idx].innerInsert(word.substring(1)); + } + + public boolean search(String word) { + if(!word.contains(".")) return this.cMap.containsKey(word); + + + return this.patternSearch(word); + } + + private boolean patternSearch(String wildcard) { + if(wildcard.length() == 0) return true; + + char c = wildcard.charAt(0); + if(c == '.') { // NOTE: wildcard를 만났을 때, 해당 depth는 검사하지 않고, 다음 번(자식) 문자들에 대해서 검색 이어나가기. + List res = new ArrayList<>(); + + for(WordDictionary children : this.child) { + if(children != null) { + res.add(children.patternSearch(wildcard.substring(1))); + } + } + + for(boolean b : res) { + if(b) return true; + } + + return false; + } + + int idx = c - 97; + if(this.child == null || this.child[idx] == null || this.child[idx].val == null) return false; + + return this.child[idx].patternSearch(wildcard.substring(1)); + } +} + +/** + * Your WordDictionary object will be instantiated and called as such: + * WordDictionary obj = new WordDictionary(); + * obj.addWord(word); + * boolean param_2 = obj.search(word); + */ + + +// 이전 TRIE 자료구조를 모른 채로 풀이했던 문제.. +class PrevWordDictionary { + + private String word; + private PrevWordDictionary leftChild; + private PrevWordDictionary rightChild; + + public PrevWordDictionary() { + this.leftChild = null; + this.rightChild = null; + this.word = null; + } + + public void addWord(String word) { + if(this.word == null) { + this.word = word; + return; + } + + // NOTE: 사전 순으로 크고 작음을 두어 이진처리. + if(this.word.compareTo(word) == 1) { + + this.rightChild = new PrevWordDictionary(); + this.rightChild.addWord(word); + } else if (this.word.compareTo(word) == -1) { + + this.leftChild = new PrevWordDictionary(); + this.leftChild.addWord(word); + } else { + // already exists. just return + } + } + + public boolean search(String word) { + if(word.contains(".")) { + // String replaced = word.replace(".", ""); + + // return word.startsWith(".") ? this.startsWith(replaced) : this.endsWith(replaced); + return this.patternSearch(word.replace(".", "")); + } + + if(this.word == null) { + return false; + } + + if(this.word.equals(word)) { + return true; + } + + if(this.rightChild == null && this.leftChild == null) { + return false; + } + + if(this.word.compareTo(word) == 1) { + return this.rightChild == null ? false : this.rightChild.search(word); + } else { + return this.leftChild == null ? false : this.leftChild.search(word); + } + } + + private boolean patternSearch(String wildcard) { + if(this.word.contains(wildcard)) return true; + + boolean left = false; + boolean right = false; + if(this.leftChild != null) { + left = this.leftChild.patternSearch(wildcard); + } + + if(this.rightChild != null) { + right = this.rightChild.patternSearch(wildcard); + } + + return left || right; + } +}