Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
64 changes: 64 additions & 0 deletions course-schedule/Geegong.java
Original file line number Diff line number Diff line change
@@ -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<List<Integer>> outdegree = new ArrayList<>();
// set outdegree
for (int idx=0; idx<numCourses; idx++) {
outdegree.add(new ArrayList<>());
}

// 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<Integer> queue = new ArrayDeque<>();
for (int idx=0; idx<numCourses; idx++) {
if (indegreeCnt[idx] == 0) {
queue.add(idx);
}
}


int currentTakenCnt = 0;
while(!queue.isEmpty()) {
int indegreeZero = queue.poll();
currentTakenCnt++;

List<Integer> targets = outdegree.get(indegreeZero);
for (int course : targets) {
indegreeCnt[course]--;
if (indegreeCnt[course] == 0) {
queue.add(course);
}
}
}

return currentTakenCnt == numCourses;
}

}
212 changes: 151 additions & 61 deletions design-add-and-search-words-data-structure/Geegong.java
Original file line number Diff line number Diff line change
@@ -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<Integer, List<Letter>> 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<Letter> 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<chArray.length; idx++) {
char ch = chArray[idx];

public boolean isMatched(char[] wordChars) {
if (ch == '.') {
// dfs, back tracking,
// . 이 있는 경우에는 그 다음 문자열부터 찾음
String temp = word.substring(idx + 1, chArray.length);

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;
for (Node next : curr.next) {
WordDictionary newWordDict = new WordDictionary(next);
if (newWordDict.search(temp)) {
return true;
}
}
return false;
}

} else {
if (curr == null || curr.getSpecificNext(ch) == null) {
return false;
}
}

return false;
curr = curr.getSpecificNext(ch);
}

return curr.end;
}
}









// 이전 기수에서 풀었던 방법, 전에는 List, Map을 이용하여 코드 풀이 하였음
// public Map<Integer, List<Letter>> 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<Letter> 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;
//
// }
// }
}

29 changes: 29 additions & 0 deletions maximum-product-subarray/Geegong.java
Original file line number Diff line number Diff line change
@@ -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<nums.length; idx++) {
int num = nums[idx];

// currMaxProd 가 변경되고 난 후에 currMinProd 를 구하기 때문에 currMinprod 를 구하기 위해 임시 저장
int tempMaxProd = currMaxProd;
currMaxProd = Math.max(num, Math.max(currMaxProd * num, currMinProd * num));
currMinProd = Math.min(num, Math.min(currMinProd * num, tempMaxProd * num));

max = Math.max(currMaxProd, max);
}

return max;
}
}
36 changes: 36 additions & 0 deletions merge-intervals/Geegong.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;

public class Geegong {

/**
* inerval 들을 오름차순으로 sorting 한후 각각의 start 와 end 를 비교하면서 머지할 수 경우를 고려하여 머지한다
* time complexity : O(N) + O(N Long N) => 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<int[]> 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()][]);
}
}