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
94 changes: 94 additions & 0 deletions design-add-and-search-words-data-structure/Geegong.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class Geegong {

/**
* case 1. Letter 라는 클래스 안에 각 char 를 가지고 있고 하나씩 순회하면서 search 를 하니 응답속도가 너무 느림..
*/
class WordDictionary {
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;

}
}
}

35 changes: 35 additions & 0 deletions find-minimum-in-rotated-sorted-array/Geegong.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
public class Geegong {

/**
* two pointer 사용
* time complexity : o(log n)
* space complexity : o(1)
*
* when nums are sorted array, binary search could be used in O(log n)
* (rotating doesn't matter)
* @param nums
* @return
*/
public int findMin(int[] nums) {
int leftIndex = 0;
int rightIndex = nums.length - 1;

while(leftIndex < rightIndex) {
int midIndex = leftIndex + ((rightIndex - leftIndex) / 2);

if (nums[midIndex] > nums[rightIndex]) {
leftIndex = midIndex + 1;
// midIndex 에 +1 하는 이유는 midIndex 값은 이미 rightIndex 보다 크다고 판단이 되기에 최솟값이 될 수 없어
// midIndex 의 값은 배제한다.
} else if (nums[midIndex] < nums[rightIndex]) {
rightIndex = midIndex - 1;
} else if (nums[midIndex] == nums[rightIndex]) { // 두개 인덱스가 같아질 수가 있나?
return nums[midIndex];
}
}

return nums[leftIndex];
}

}

63 changes: 63 additions & 0 deletions longest-increasing-subsequence/Geegong.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import java.util.Arrays;

public class Geegong {

/**
* case 1. binarySearch 를 이용, 범위를 1개의 원소부터 시작해서 점차 늘릴 수 있는 LIS 를 별도 변수에서 관리
* 그리고 정렬이 되어가는 배열을 따로 저장하는 배열도 필요
* Patience Sorting 아이디어 (?) -> 찾아보자
* time complexity :
* O(log n) - binary search 이고
* 위 bs 를 각 원소별로 진행하기 때문에 o(n log n)
* space complexity : O(n)
*
* case 2. DP
* dp[i] => nums 의 i 번째 인덱스까지의 LIS 최장 길이를 의미
* time complexity : O(n^2)
* space complexity : O(n)
*
* @param nums
* @return
*/
// public static int lengthOfLIS(int[] nums) {
// int n = nums.length;
// int[] tails = new int[n];
// int size = 0;
//
// for (int x : nums) {
// // 0 ~ size 안에서 이분탐색으로 넣을 수 있는 자리가 있으면 그 자리의 index 리턴 (따라서 tc 는 o(n log n)
// // 넣을 수 없으면 음수값을 리턴하는데 ret = - (insertionPosition - 1)
// // (0~size) 안에서 x 가 들어갈 수 있는 index는?=> insertionPosition = - (ret + 1) 이렇게 획득
// int i = Arrays.binarySearch(tails, 0, size, x);
// if (i < 0) i = -(i + 1); // lower_bound
// tails[i] = x;
// // size 는 nums 안에 원소들을 하나씩 훑어가면서 지금까지 LIS의 최장 길이
// if (i == size) size++;
// }
// return size;
// }

public static int lengthOfLIS(int[] nums) {
int[] dp = new int[nums.length + 1];
int maxLIS = 0;

for (int index=0; index<nums.length; index++) {
dp[index] = 1; // 첫번쨰 인덱스부터 LIS 는 1이라고 보자
for (int innerIndex=0; innerIndex<index; innerIndex++) {
// ex) {10,9,2,5,3,7,101,18};
if (nums[innerIndex] < nums[index]) {
//dp[index] = dp[index] + 1; => 맨 처음에는 이렇게 생각했으나
dp[index] = Math.max(dp[index], dp[innerIndex] + 1);
// dp[innerIndex] + 1 에서 +1을 한 이유는 innerIndex의 값과 index의 값까지가 LIS가 될 것이기 때문에 더해진 것
}
}

maxLIS = Math.max(maxLIS, dp[index]);
}

return maxLIS;
}


}

79 changes: 79 additions & 0 deletions spiral-matrix/Geegong.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
import java.util.ArrayList;
import java.util.List;

public class Geegong {

/**
* direction vector 와 vistited 배열을 이용해 메모이제이션을 활용하여 풀어보기
* time complexity : o(n)
* space complexity : o(n) - result 용
* @param matrix
* @return
*/
// move Colum direction , move Row Direction
public int[][] directionVectors = {{0,1}, {1,0}, {0,-1}, {-1, 0}};
public List<Integer> spiralOrder(int[][] matrix) {

List<Integer> result = new ArrayList<>(matrix.length * matrix[0].length);

// for memoization, 방문한 matrix의 인덱스들을 저장
// int 배열은 기본으로 0 이 초기화
int[][] visited = new int[matrix.length][matrix[0].length];

makeSpiralMatrix(matrix, 0,0, 0, result, visited);

return result;
}

public void makeSpiralMatrix(int[][] matrix, int startRowIdx, int startColIdx, int directionOrder, List<Integer> result, int[][] visited) {
if (startRowIdx < 0 || startRowIdx >= matrix.length || startColIdx < 0 || startColIdx >= matrix[0].length) {
return;
}

// 방문했던 녀석을 다시 찾아온거라면 다 돌았다고 판단하고 recursive 종료
if (visited[startRowIdx][startColIdx] == 1) {
return;
}

// 이번 순서의 vector 를 가져온다
int[] direction = directionVectors[directionOrder];

// row, col 각각 어떤 방향으로 움직일지 지정
int moveRowPos = direction[0];
int moveColPos = direction[1];

int count = 0;

int rowIndex = startRowIdx + (moveRowPos * count);
int colIndex = startColIdx + (moveColPos * count);

do {
int currentVal = matrix[rowIndex][colIndex];
result.add(currentVal);
visited[rowIndex][colIndex] = 1;

count++;
rowIndex = startRowIdx + (moveRowPos * count);
colIndex = startColIdx + (moveColPos * count);
if (colIndex < 0 || colIndex >= matrix[0].length || rowIndex < 0 || rowIndex >= matrix.length) {
break;
}

} while(visited[rowIndex][colIndex] != 1);

// vector 리스트들은 0번째, 1번째, 2번째, 3번째, 0번째, 1번째 .. 이 순서대로 꺼내서 사용한다
int nextDirectionOrder = directionOrder + 1 >= directionVectors.length ? 0 : directionOrder + 1;
// 다음 방향을 미리 지정
int[] nextDirection = directionVectors[nextDirectionOrder];

// 다음 방향의 시작점 미리 지정
count--;
int nextStartRowIdx = startRowIdx + (moveRowPos * count) + nextDirection[0];
int nextStartColIdx = startColIdx + (moveColPos * count) + nextDirection[1];

makeSpiralMatrix(matrix, nextStartRowIdx, nextStartColIdx, nextDirectionOrder, result, visited);
}
}



38 changes: 38 additions & 0 deletions valid-parentheses/Geegong.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import java.util.HashMap;
import java.util.Stack;

public class Geegong {

/**
* stack 자료구조 사용
* 닫는 부분만 hashMap의 key 값으로 서로 페어가 되는 값을 value 로 한다.
* stack 자료구조는 닫는 bracket이 아니면 push 해서 넣고 닫는 bracket 만 체크를 하는데
* stack 에서 pop 을 하는데 이떄 map의 value와 다르면 false
*
* time complexity : o(n)
* space complexity : o(1)
* @param s
* @return
*/
public boolean isValid(String s) {
HashMap<Character, Character> map = new HashMap<Character, Character>();
map.put(')', '(');
map.put(']', '[');
map.put('}', '{');

Stack<Character> stack = new Stack<Character>();
for (int i=0; i<s.length(); i++) {
Character ch = s.charAt(i);
if (map.containsKey(ch)) {
if (stack.isEmpty() || map.get(ch) != stack.pop()) {
return false;
}
} else {
stack.push(ch);
}
}

return stack.isEmpty();
}
}