diff --git a/course-schedule/Geegong.java b/course-schedule/Geegong.java new file mode 100644 index 0000000000..a5d0373f9d --- /dev/null +++ b/course-schedule/Geegong.java @@ -0,0 +1,64 @@ +import java.util.*; + +public class Geegong { + + /** + * in-degree array, graph, queue 이용 + * directed acyclic graph (DAG) 문제.. + * in-degree array : 타 노드에서 유입이 되는 갯수 + * graph : [a,b] 이렇게 있으면 b -> a 로 가는 방향 edge 를 표현 + * queue : in-degree array 에서 0 인 노드들. 즉 바로 수강할 수 있는 녀석들을 차례차례 넣어 카운팅할 예정 + * (예전에도 동일하게 풀어서 .. 한번 더 복습하는 느낌으로 풀었습니다) + * @param numCourses + * @param prerequisites + * @return + */ + public boolean canFinish(int numCourses, int[][] prerequisites) { + + int[] indegreeCnt = new int[numCourses]; + List> outdegree = new ArrayList<>(); + // set outdegree + for (int idx=0; idx()); + } + + // set indgree, outdegree, candidateNoIndgree + for (int[] pre : prerequisites) { + int course = pre[0]; + int prerequisite = pre[1]; + + if (course == prerequisite) { + return false; + } + + outdegree.get(prerequisite).add(course); + indegreeCnt[course]++; + } + + // find indgree zero + Queue queue = new ArrayDeque<>(); + for (int idx=0; idx targets = outdegree.get(indegreeZero); + for (int course : targets) { + indegreeCnt[course]--; + if (indegreeCnt[course] == 0) { + queue.add(course); + } + } + } + + return currentTakenCnt == numCourses; + } + +} diff --git a/design-add-and-search-words-data-structure/Geegong.java b/design-add-and-search-words-data-structure/Geegong.java index 08dfc87e27..c3774e3c00 100644 --- a/design-add-and-search-words-data-structure/Geegong.java +++ b/design-add-and-search-words-data-structure/Geegong.java @@ -1,94 +1,184 @@ -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; +import java.util.*; public class Geegong { /** - * case 1. Letter 라는 클래스 안에 각 char 를 가지고 있고 하나씩 순회하면서 search 를 하니 응답속도가 너무 느림.. + * 이전 기수와는 다르게 배열을 활용해서 문제 풀이 + * time complexity : O(26^N) (worst case) + * space complexity : O(26 * N) => O(N) */ - class WordDictionary { - public Map> wordsLengthMap; + public static class Node { + private Node[] next = new Node[26]; + private boolean end; + + public void setNext(char ch) { + int idx = ch - 'a'; + if (next[idx] == null) { + next[idx] = new Node(); + } + } - public WordDictionary() { - this.wordsLengthMap = new HashMap<>(); + public Node getSpecificNext(char ch) { + int idx = ch - 'a'; + return this.next[idx]; } - public void addWord(String word) { - char[] wordChars = word.toCharArray(); + public void setEnd(boolean isEnd) { + this.end = isEnd; + } + } - Letter prev = new Letter(null); - Letter root = new Letter(prev); - for (char wordChar : wordChars) { - Letter curr = new Letter(wordChar, false); - prev.nextLetter = curr; - prev = curr; - } - prev.isEnd = true; - wordsLengthMap.computeIfAbsent(wordChars.length, ArrayList::new).add(root.nextLetter); + /** + * case 1. Letter 라는 클래스 안에 각 char 를 가지고 있고 하나씩 순회하면서 search 를 하니 응답속도가 너무 느림.. + */ + public class WordDictionary { + private Node entry; + + public WordDictionary(Node entry) { + this.entry = entry; } - public boolean search(String word) { - char[] wordChars = word.toCharArray(); - int length = wordChars.length; + public WordDictionary() { } - if (!wordsLengthMap.containsKey(length)) { - return false; - } + public void addWord(String word) { + char[] chArray = word.toCharArray(); - List letters = wordsLengthMap.get(length); - for (Letter letter : letters) { - if (letter.isMatched(wordChars)) { - return true; - } + if (entry == null) { + entry = new Node(); } - - return false; + Node curr = entry; + for (char ch : chArray) { + curr.setNext(ch); + curr = curr.getSpecificNext(ch); + } + curr.setEnd(true); } - } - public static class Letter { - public char currentLetterOfAsciiCode; // '?'-'a' - public Letter nextLetter; - public boolean isEnd; // 마지막 글자 인지 여부 + public boolean search(String word) { - public Letter(Letter next) { - this.nextLetter = next; - } + char[] chArray = word.toCharArray(); - public Letter(char wordChar, boolean isEnd) { - this.currentLetterOfAsciiCode = wordChar; - this.isEnd = isEnd; - } + Node curr = entry; + for (int idx = 0; idx> wordsLengthMap; +// +// public WordDictionary() { +// this.wordsLengthMap = new HashMap<>(); +// } +// +// public void addWord(String word) { +// char[] wordChars = word.toCharArray(); +// +// Letter prev = new Letter(null); +// Letter root = new Letter(prev); +// for (char wordChar : wordChars) { +// Letter curr = new Letter(wordChar, false); +// +// prev.nextLetter = curr; +// +// prev = curr; +// } +// +// prev.isEnd = true; +// +// wordsLengthMap.computeIfAbsent(wordChars.length, ArrayList::new).add(root.nextLetter); +// } +// +// public boolean search(String word) { +// char[] wordChars = word.toCharArray(); +// int length = wordChars.length; +// +// if (!wordsLengthMap.containsKey(length)) { +// return false; +// } +// +// List letters = wordsLengthMap.get(length); +// for (Letter letter : letters) { +// if (letter.isMatched(wordChars)) { +// return true; +// } +// } +// +// return false; +// } +// } +// +// public static class Letter { +// public char currentLetterOfAsciiCode; // '?'-'a' +// public Letter nextLetter; +// public boolean isEnd; // 마지막 글자 인지 여부 +// +// public Letter(Letter next) { +// this.nextLetter = next; +// } +// +// public Letter(char wordChar, boolean isEnd) { +// this.currentLetterOfAsciiCode = wordChar; +// this.isEnd = isEnd; +// } +// +// public boolean isMatched(char[] wordChars) { +// +// Letter current = this.nextLetter; +// // 본인 시점으로 부터 wordChars 마지막까지 체크 +// for (char wordChar : wordChars) { +// +// // . 이면 그냥 패스 +// boolean isMatched = wordChar == '.' || wordChar == current.currentLetterOfAsciiCode; +// if (isMatched) { +// if (current.isEnd) { +// return true; +// } else { +// current = current.nextLetter; +// } +// +// } else { +// return false; +// } +// } +// +// return false; +// +// } +// } } diff --git a/maximum-product-subarray/Geegong.java b/maximum-product-subarray/Geegong.java new file mode 100644 index 0000000000..69b83d6ca0 --- /dev/null +++ b/maximum-product-subarray/Geegong.java @@ -0,0 +1,29 @@ +public class Geegong { + + /** + * kadane's algorithm 으로 풀이 + * 위 알고리즘은 contiguous array 에 대한 문제를 풀이할 때 자주 쓰임 + * time complexity : O(N) + * space complexity : O(1) + * @param nums + * @return + */ + public int maxProduct(int[] nums) { + int currMaxProd = nums[0]; + int currMinProd = nums[0]; + int max = nums[0]; + + for (int idx=1; idx O(N log N) + * space complexity : O(N) + * @param intervals + * @return + */ + public int[][] merge(int[][] intervals) { + // 1. sort intervals + Arrays.sort(intervals, Comparator.comparingInt(o -> o[0])); + List result = new ArrayList<>(); + + result.add(intervals[0]); + for (int i = 1; i < intervals.length; i++) { + int[] last = result.get(result.size() - 1); + int[] cur = intervals[i]; + + if (last[1] >= cur[0]) { + // merge (update last end) + last[1] = Math.max(last[1], cur[1]); + } else { + // no overlap + result.add(cur); + } + } + + return result.toArray(t -> new int[result.size()][]); + } +}