diff --git a/best-time-to-buy-and-sell-stock/se6816.java b/best-time-to-buy-and-sell-stock/se6816.java new file mode 100644 index 000000000..d2a081c3e --- /dev/null +++ b/best-time-to-buy-and-sell-stock/se6816.java @@ -0,0 +1,43 @@ + +/** + dp를 이용한 방식? + prices의 길이 -> N + 시간복잡도 : O(N^2) -> 시간 초과 + 공간복잡도 : O(N) + */ +class Solution2 { + public int maxProfit(int[] prices) { + int[] dp =new int[prices.length]; + for(int i = 0; i < dp.length; i++) { + for(int j = 0; j < i; j++) { + dp[i] = Math.max(dp[i], prices[i] - prices[j]); + } + } + + return Arrays.stream(dp) + .max() + .getAsInt(); + } +} + +/** + 이전 연산 값을 기억할 필요 없이 특정 인덱스 지점까지의 최소 값만 알면 되므로, + + prices의 길이 -> N + 시간복잡도 : O(N) + 공간복잡도 : O(1) + */ +class Solution { + public int maxProfit(int[] prices) { + int min=prices[0]; + int profit=0; + for(int i=1; i N + 시간 복잡도 : O(N) + 공간 복잡도 : O(N) +*/ +class Solution { + public List> groupAnagrams(String[] strs) { + List> result = new ArrayList<>(); + Map> hashMap = new HashMap<>(); + for(int i=0; i list = hashMap.getOrDefault(word, new ArrayList<>()); + list.add(strs[i]); + hashMap.put(word,list); + } + for(Map.Entry> entry : hashMap.entrySet()){ + List list = entry.getValue(); + result.add(list); + } + return result; + } +} + + + diff --git a/implement-trie-prefix-tree/se6816.java b/implement-trie-prefix-tree/se6816.java new file mode 100644 index 000000000..857c2162c --- /dev/null +++ b/implement-trie-prefix-tree/se6816.java @@ -0,0 +1,92 @@ +/** + 연결 리스트를 통해, 트리 구조를 만들고 탐색하는 방식 +*/ +class Trie { + public Map wordMap; + + public Trie() { + wordMap = new HashMap<>(); + } + + public void insert(String word) { + WordNode wordNode = null; + char ch = word.charAt(0); + wordNode = wordMap.get(ch); + + if(wordNode == null) { + boolean isFirstWord = word.length() == 1; + wordNode = new WordNode(ch, isFirstWord); + wordMap.put(ch, wordNode); + } + + for(int idx = 1; idx < word.length(); idx++) { + char target = word.charAt(idx); + boolean isLeaf = word.length() - 1 == idx; + wordNode = wordNode.next.computeIfAbsent(target, key -> new WordNode(key, isLeaf)); + } + wordNode.isLeaf = true; + } + + public boolean search(String word) { + + WordNode wordNode = null; + char ch = word.charAt(0); + wordNode = wordMap.get(ch); + if (wordNode == null) return false; + + + for(int idx = 1; idx < word.length(); idx++) { + char target = word.charAt(idx); + if (!wordNode.next.containsKey(target)) { + return false; + } + wordNode = wordNode.next.get(target); + } + + return wordNode.isLeaf; + } + + public boolean startsWith(String word) { + + WordNode wordNode = null; + char ch = word.charAt(0); + wordNode = wordMap.get(ch); + if (wordNode == null) return false; + + + for(int idx = 1; idx < word.length(); idx++) { + char target = word.charAt(idx); + if (!wordNode.next.containsKey(target)) { + return false; + } + wordNode = wordNode.next.get(target); + } + + return true; + } +} + +class WordNode { + char ch; + Map next; + boolean isLeaf; + + public WordNode(char ch) { + this(ch, false); + } + + public WordNode(char ch, boolean isLeaf) { + next = new HashMap<>(); + this.ch = ch; + this.isLeaf = isLeaf; + } + +} + +/** + * Your Trie object will be instantiated and called as such: + * Trie obj = new Trie(); + * obj.insert(word); + * boolean param_2 = obj.search(word); + * boolean param_3 = obj.startsWith(prefix); + */ diff --git a/word-break/se6816.java b/word-break/se6816.java new file mode 100644 index 000000000..e35702d3f --- /dev/null +++ b/word-break/se6816.java @@ -0,0 +1,120 @@ +/** + Tries 자료구조를 구현하고, 이를 통해 단어를 탐색하는 방식 + visited[] 방문 배열을 추가하여, 이전에 방문했던 인덱스에 대해서는 무시 + */ +class WordMap { + public Map wordMap; + + public WordMap() { + wordMap = new HashMap<>(); + } + + public List search(String word, int idx) { + List idxList = new ArrayList<>(); + + WordNode wordNode = null; + char ch = word.charAt(idx); + wordNode = wordMap.get(ch); + if (wordNode == null) return idxList; + + if(wordNode.isLeaf) { + idxList.add(idx + 1); + } + idx++; + + for(; idx < word.length(); idx++) { + char target = word.charAt(idx); + if (!wordNode.next.containsKey(target)) { + break; + } + wordNode = wordNode.next.get(target); + if (wordNode.isLeaf) { + idxList.add(idx + 1); + } + } + + return idxList; + } + + public void add(String word) { + WordNode wordNode = null; + char ch = word.charAt(0); + wordNode = wordMap.get(ch); + + if(wordNode == null) { + boolean isFirstWord = word.length() == 1; + wordNode = new WordNode(ch, isFirstWord); + wordMap.put(ch, wordNode); + } + + for(int idx = 1; idx < word.length(); idx++) { + char target = word.charAt(idx); + boolean isLeaf = word.length() - 1 == idx; + wordNode = wordNode.next.computeIfAbsent(target, key -> new WordNode(key, isLeaf)); + } + + wordNode.isLeaf = true; + + } + +} + +class WordNode { + char ch; + Map next; + boolean isLeaf; + + public WordNode(char ch) { + this(ch, false); + } + + public WordNode(char ch, boolean isLeaf) { + next = new HashMap<>(); + this.ch = ch; + this.isLeaf = isLeaf; + } + +} + +class Solution { + public static WordMap wordMap; + public boolean wordBreak(String s, List wordDict) { + boolean[] visited = new boolean[s.length()]; + initWordMap(wordDict); + if(s.length() == 1) return wordMap.wordMap.containsKey(s.charAt(0)) && wordMap.wordMap.get(s.charAt(0)).isLeaf; + + Queue que = new LinkedList<>(); + boolean result = false; + que.add(0); + visited[0] = true; + loop: + while(!que.isEmpty()) { + int idx = que.poll(); + List idxList = wordMap.search(s, idx); + for(int i : idxList) { + if(i == s.length()) { + result = true; + break loop; + } + + if(!visited[i]) { + que.add(i); + visited[i] = true; + } + } + } + + return result; + + + + } + + public void initWordMap(List wordDict) { + wordMap = new WordMap(); + for(String word : wordDict) { + wordMap.add(word); + } + } +} +