diff --git a/container-with-most-water/imsosleepy.java b/container-with-most-water/imsosleepy.java new file mode 100644 index 000000000..4d319e391 --- /dev/null +++ b/container-with-most-water/imsosleepy.java @@ -0,0 +1,19 @@ +// 투포인터를 활용한 시간복잡도 O(N)으로 풀면된다. +// 중요한건 언제 이동하냐?를 정의하는건데, 전체 물양이 줄어들면 상대적으로 작은 쪽을 이동시키면된다. +class Solution { + public int maxArea(int[] height) { + int left = 0; + int right = height.length-1; + int maxWater = 0; + while(left < right) { + int max = Math.min(height[left], height[right]) * (right - left); + maxWater = Math.max(max,maxWater); + if (height[left] < height[right]) { + left++; + } else { + right--; + } + } + return maxWater; + } +} diff --git a/design-add-and-search-words-data-structure/imsosleepy.java b/design-add-and-search-words-data-structure/imsosleepy.java new file mode 100644 index 000000000..412ad1cec --- /dev/null +++ b/design-add-and-search-words-data-structure/imsosleepy.java @@ -0,0 +1,82 @@ +// GPT가 거의 풀어준 Trie를 이용한 풀이. 알파벳의 존재 여부를 26개의 노드에 저장한다. +// 다음 노드를 찾아가는 방식은 재귀적으로 구성된다. 단어의 끝은 endOfWord로 관리됨. +// 혼자서는 절대 못 풀었을 문제 +class WordDictionary { + private TrieNode root; + + private static class TrieNode { + private TrieNode[] children; + private boolean isEndOfWord; + + public TrieNode() { + this.children = new TrieNode[26]; + this.isEndOfWord = false; + } + } + + public WordDictionary() { + root = new TrieNode(); + } + + public void addWord(String word) { + TrieNode current = root; + for (char ch : word.toCharArray()) { + int index = ch - 'a'; + if (current.children[index] == null) { + current.children[index] = new TrieNode(); + } + current = current.children[index]; + } + current.isEndOfWord = true; + } + + public boolean search(String word) { + return searchInNode(word, root, 0); + } + + private boolean searchInNode(String word, TrieNode node, int index) { + if (index == word.length()) { + return node.isEndOfWord; + } + + char ch = word.charAt(index); + if (ch == '.') { + for (TrieNode child : node.children) { + if (child != null && searchInNode(word, child, index + 1)) { + return true; + } + } + return false; + } else { + int charIndex = ch - 'a'; + TrieNode child = node.children[charIndex]; + if (child == null) { + return false; + } + return searchInNode(word, child, index + 1); + } + } +} + +// 내가 생각한 첫번째 풀이. 정규표현식을 이용하면 될거라 생각했는데.. +class WordDictionary { + private List words; + + public WordDictionary() { + words = new ArrayList<>(); + } + + public void addWord(String word) { + words.add(word); + } + + public boolean search(String word) { + String regex = word.replace(".", "[a-z]"); + for (String w : words) { + if (w.matches(regex)) { + return true; + } + } + return false; + } +} diff --git a/longest-increasing-subsequence/imsosleepy.java b/longest-increasing-subsequence/imsosleepy.java new file mode 100644 index 000000000..3685e144e --- /dev/null +++ b/longest-increasing-subsequence/imsosleepy.java @@ -0,0 +1,21 @@ +// 이진 트리로 값을 변경해가면서 해결하면된다. +// 기존에 있던 노드에 위치한 값보다 작은 값이 등장하면 값이 치환된다는 개념만 이해하면 쉽다. +// 자바에서는 콜렉션에서 바이너리 서치를 제공해서 편하게 구현가능 +class Solution { + public int lengthOfLIS(int[] nums) { + List sub = new ArrayList<>(); + + for (int num : nums) { + int pos = Collections.binarySearch(sub, num); + if (pos < 0) { + pos = -(pos + 1); + } + if (pos < sub.size()) { + sub.set(pos, num); + } else { + sub.add(num); + } + } + return sub.size(); + } +} diff --git a/spiral-matrix/imsosleepy.java b/spiral-matrix/imsosleepy.java new file mode 100644 index 000000000..54f3073a6 --- /dev/null +++ b/spiral-matrix/imsosleepy.java @@ -0,0 +1,36 @@ +// 처음보는 시뮬레이션 문제라 그냥 풀었음 +// 별다른 알고리즘이 필요없다. +public class Solution { + public List spiralOrder(int[][] matrix) { + List result = new ArrayList<>(); + if (matrix == null || matrix.length == 0) return result; + + int rows = matrix.length; + int cols = matrix[0].length; + boolean[][] visited = new boolean[rows][cols]; + + int[] dRow = {0, 1, 0, -1}; + int[] dCol = {1, 0, -1, 0}; + + int row = 0, col = 0, dir = 0; + + for (int i = 0; i < rows * cols; i++) { + result.add(matrix[row][col]); + visited[row][col] = true; + + int nextRow = row + dRow[dir]; + int nextCol = col + dCol[dir]; + + if (nextRow < 0 || nextRow >= rows || nextCol < 0 || nextCol >= cols || visited[nextRow][nextCol]) { + dir = (dir + 1) % 4; + nextRow = row + dRow[dir]; + nextCol = col + dCol[dir]; + } + + row = nextRow; + col = nextCol; + } + + return result; + } +} diff --git a/valid-parentheses/imsosleepy.java b/valid-parentheses/imsosleepy.java new file mode 100644 index 000000000..a162785a3 --- /dev/null +++ b/valid-parentheses/imsosleepy.java @@ -0,0 +1,81 @@ +// 스택을 사용해 시간복잡도를 O(N)으로 풀어야하는 문제. +// toCharArray로 문자열을 자르는 시간을 대폭 줄일 수 있다. charAt도 그닥 좋은 방법은 아닌듯 +class Solution { + public boolean isValid(String s) { + Stack stack = new Stack<>(); + + if(s.length() == 1) return false; + boolean valid = false; + for(char c : s.toCharArray()) { + valid = false; + if(c == '(' || c == '{' || c == '[') { + stack.push(c); + continue; + } + + if(!stack.isEmpty() && c == ')' && stack.peek() == '(') { + valid = true; + stack.pop(); + continue; + } + + if(!stack.isEmpty() && c == '}' && stack.peek() == '{') { + valid = true; + stack.pop(); + continue; + } + + if(!stack.isEmpty() && c == ']' && stack.peek() == '[') { + valid = true; + stack.pop(); + continue; + } + break; + } + + if (!stack.isEmpty()) return false; + + return valid; + } +} + +// 첫 풀이. s.split("") 하나가 제법 많은 시간 복잡도를 사용한다. +// String 객체할당과 배열 재생성 등의 과정을 거친다. 그래서... 다른 방법을 찾아봄 +class Solution { + public boolean isValid(String s) { + Stack stack = new Stack<>(); + + if(s.length() == 1) return false; + boolean valid = false; + for(String str : s.split("")) { + valid = false; + if(str.equals("(") || str.equals("{") || str.equals("[") ) { + stack.push(str); + continue; + } + + if(!stack.isEmpty() && str.equals(")") && stack.peek().equals("(")) { + valid = true; + stack.pop(); + continue; + } + + if(!stack.isEmpty() && str.equals("]") && stack.peek().equals("[")) { + valid = true; + stack.pop(); + continue; + } + + if(!stack.isEmpty() && str.equals("}") && stack.peek().equals("{")) { + valid = true; + stack.pop(); + continue; + } + break; + } + + if (!stack.isEmpty()) return false; + + return valid; + } +}