Skip to content

Commit 668e45f

Browse files
committed
- weeks 06
1 parent 81e874c commit 668e45f

File tree

4 files changed

+271
-0
lines changed

4 files changed

+271
-0
lines changed
Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
import java.util.ArrayList;
2+
import java.util.HashMap;
3+
import java.util.List;
4+
import java.util.Map;
5+
6+
public class Geegong {
7+
8+
/**
9+
* case 1. Letter 라는 클래스 안에 각 char 를 가지고 있고 하나씩 순회하면서 search 를 하니 응답속도가 너무 느림..
10+
*/
11+
class WordDictionary {
12+
public Map<Integer, List<Letter>> wordsLengthMap;
13+
14+
public WordDictionary() {
15+
this.wordsLengthMap = new HashMap<>();
16+
}
17+
18+
public void addWord(String word) {
19+
char[] wordChars = word.toCharArray();
20+
21+
Letter prev = new Letter(null);
22+
Letter root = new Letter(prev);
23+
for (char wordChar : wordChars) {
24+
Letter curr = new Letter(wordChar, false);
25+
26+
prev.nextLetter = curr;
27+
28+
prev = curr;
29+
}
30+
31+
prev.isEnd = true;
32+
33+
wordsLengthMap.computeIfAbsent(wordChars.length, ArrayList::new).add(root.nextLetter);
34+
}
35+
36+
public boolean search(String word) {
37+
char[] wordChars = word.toCharArray();
38+
int length = wordChars.length;
39+
40+
if (!wordsLengthMap.containsKey(length)) {
41+
return false;
42+
}
43+
44+
List<Letter> letters = wordsLengthMap.get(length);
45+
for (Letter letter : letters) {
46+
if (letter.isMatched(wordChars)) {
47+
return true;
48+
}
49+
}
50+
51+
return false;
52+
}
53+
}
54+
55+
public static class Letter {
56+
public char currentLetterOfAsciiCode; // '?'-'a'
57+
public Letter nextLetter;
58+
public boolean isEnd; // 마지막 글자 인지 여부
59+
60+
public Letter(Letter next) {
61+
this.nextLetter = next;
62+
}
63+
64+
public Letter(char wordChar, boolean isEnd) {
65+
this.currentLetterOfAsciiCode = wordChar;
66+
this.isEnd = isEnd;
67+
}
68+
69+
public boolean isMatched(char[] wordChars) {
70+
71+
Letter current = this.nextLetter;
72+
// 본인 시점으로 부터 wordChars 마지막까지 체크
73+
for (char wordChar : wordChars) {
74+
75+
// . 이면 그냥 패스
76+
boolean isMatched = wordChar == '.' || wordChar == current.currentLetterOfAsciiCode;
77+
if (isMatched) {
78+
if (current.isEnd) {
79+
return true;
80+
} else {
81+
current = current.nextLetter;
82+
}
83+
84+
} else {
85+
return false;
86+
}
87+
}
88+
89+
return false;
90+
91+
}
92+
}
93+
}
94+
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
public class Geegong {
2+
3+
/**
4+
* two pointer 사용
5+
* time complexity : o(log n)
6+
* space complexity : o(1)
7+
*
8+
* when nums are sorted array, binary search could be used in O(log n)
9+
* (rotating doesn't matter)
10+
* @param nums
11+
* @return
12+
*/
13+
public int findMin(int[] nums) {
14+
int leftIndex = 0;
15+
int rightIndex = nums.length - 1;
16+
17+
while(leftIndex < rightIndex) {
18+
int midIndex = leftIndex + ((rightIndex - leftIndex) / 2);
19+
20+
if (nums[midIndex] > nums[rightIndex]) {
21+
leftIndex = midIndex + 1;
22+
// midIndex 에 +1 하는 이유는 midIndex 값은 이미 rightIndex 보다 크다고 판단이 되기에 최솟값이 될 수 없어
23+
// midIndex 의 값은 배제한다.
24+
} else if (nums[midIndex] < nums[rightIndex]) {
25+
rightIndex = midIndex - 1;
26+
} else if (nums[midIndex] == nums[rightIndex]) { // 두개 인덱스가 같아질 수가 있나?
27+
return nums[midIndex];
28+
}
29+
}
30+
31+
return nums[leftIndex];
32+
}
33+
34+
}
35+
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
import java.util.Arrays;
2+
3+
public class Geegong {
4+
5+
/**
6+
* case 1. binarySearch 를 이용, 범위를 1개의 원소부터 시작해서 점차 늘릴 수 있는 LIS 를 별도 변수에서 관리
7+
* 그리고 정렬이 되어가는 배열을 따로 저장하는 배열도 필요
8+
* Patience Sorting 아이디어 (?) -> 찾아보자
9+
* time complexity :
10+
* O(log n) - binary search 이고
11+
* 위 bs 를 각 원소별로 진행하기 때문에 o(n log n)
12+
* space complexity : O(n)
13+
*
14+
* case 2. DP
15+
* dp[i] => nums 의 i 번째 인덱스까지의 LIS 최장 길이를 의미
16+
* time complexity : O(n^2)
17+
* space complexity : O(n)
18+
*
19+
* @param nums
20+
* @return
21+
*/
22+
// public static int lengthOfLIS(int[] nums) {
23+
// int n = nums.length;
24+
// int[] tails = new int[n];
25+
// int size = 0;
26+
//
27+
// for (int x : nums) {
28+
// // 0 ~ size 안에서 이분탐색으로 넣을 수 있는 자리가 있으면 그 자리의 index 리턴 (따라서 tc 는 o(n log n)
29+
// // 넣을 수 없으면 음수값을 리턴하는데 ret = - (insertionPosition - 1)
30+
// // (0~size) 안에서 x 가 들어갈 수 있는 index는?=> insertionPosition = - (ret + 1) 이렇게 획득
31+
// int i = Arrays.binarySearch(tails, 0, size, x);
32+
// if (i < 0) i = -(i + 1); // lower_bound
33+
// tails[i] = x;
34+
// // size 는 nums 안에 원소들을 하나씩 훑어가면서 지금까지 LIS의 최장 길이
35+
// if (i == size) size++;
36+
// }
37+
// return size;
38+
// }
39+
40+
public static int lengthOfLIS(int[] nums) {
41+
int[] dp = new int[nums.length + 1];
42+
int maxLIS = 0;
43+
44+
for (int index=0; index<nums.length; index++) {
45+
dp[index] = 1; // 첫번쨰 인덱스부터 LIS 는 1이라고 보자
46+
for (int innerIndex=0; innerIndex<index; innerIndex++) {
47+
// ex) {10,9,2,5,3,7,101,18};
48+
if (nums[innerIndex] < nums[index]) {
49+
//dp[index] = dp[index] + 1; => 맨 처음에는 이렇게 생각했으나
50+
dp[index] = Math.max(dp[index], dp[innerIndex] + 1);
51+
// dp[innerIndex] + 1 에서 +1을 한 이유는 innerIndex의 값과 index의 값까지가 LIS가 될 것이기 때문에 더해진 것
52+
}
53+
}
54+
55+
maxLIS = Math.max(maxLIS, dp[index]);
56+
}
57+
58+
return maxLIS;
59+
}
60+
61+
62+
}
63+

spiral-matrix/Geegong.java

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
import java.util.ArrayList;
2+
import java.util.List;
3+
4+
public class Geegong {
5+
6+
/**
7+
* direction vector 와 vistited 배열을 이용해 메모이제이션을 활용하여 풀어보기
8+
* time complexity : o(n)
9+
* space complexity : o(n) - result 용
10+
* @param matrix
11+
* @return
12+
*/
13+
// move Colum direction , move Row Direction
14+
public int[][] directionVectors = {{0,1}, {1,0}, {0,-1}, {-1, 0}};
15+
public List<Integer> spiralOrder(int[][] matrix) {
16+
17+
List<Integer> result = new ArrayList<>(matrix.length * matrix[0].length);
18+
19+
// for memoization, 방문한 matrix의 인덱스들을 저장
20+
// int 배열은 기본으로 0 이 초기화
21+
int[][] visited = new int[matrix.length][matrix[0].length];
22+
23+
makeSpiralMatrix(matrix, 0,0, 0, result, visited);
24+
25+
return result;
26+
}
27+
28+
public void makeSpiralMatrix(int[][] matrix, int startRowIdx, int startColIdx, int directionOrder, List<Integer> result, int[][] visited) {
29+
if (startRowIdx < 0 || startRowIdx >= matrix.length || startColIdx < 0 || startColIdx >= matrix[0].length) {
30+
return;
31+
}
32+
33+
// 방문했던 녀석을 다시 찾아온거라면 다 돌았다고 판단하고 recursive 종료
34+
if (visited[startRowIdx][startColIdx] == 1) {
35+
return;
36+
}
37+
38+
// 이번 순서의 vector 를 가져온다
39+
int[] direction = directionVectors[directionOrder];
40+
41+
// row, col 각각 어떤 방향으로 움직일지 지정
42+
int moveRowPos = direction[0];
43+
int moveColPos = direction[1];
44+
45+
int count = 0;
46+
47+
int rowIndex = startRowIdx + (moveRowPos * count);
48+
int colIndex = startColIdx + (moveColPos * count);
49+
50+
do {
51+
int currentVal = matrix[rowIndex][colIndex];
52+
result.add(currentVal);
53+
visited[rowIndex][colIndex] = 1;
54+
55+
count++;
56+
rowIndex = startRowIdx + (moveRowPos * count);
57+
colIndex = startColIdx + (moveColPos * count);
58+
if (colIndex < 0 || colIndex >= matrix[0].length || rowIndex < 0 || rowIndex >= matrix.length) {
59+
break;
60+
}
61+
62+
} while(visited[rowIndex][colIndex] != 1);
63+
64+
// vector 리스트들은 0번째, 1번째, 2번째, 3번째, 0번째, 1번째 .. 이 순서대로 꺼내서 사용한다
65+
int nextDirectionOrder = directionOrder + 1 >= directionVectors.length ? 0 : directionOrder + 1;
66+
// 다음 방향을 미리 지정
67+
int[] nextDirection = directionVectors[nextDirectionOrder];
68+
69+
// 다음 방향의 시작점 미리 지정
70+
count--;
71+
int nextStartRowIdx = startRowIdx + (moveRowPos * count) + nextDirection[0];
72+
int nextStartColIdx = startColIdx + (moveColPos * count) + nextDirection[1];
73+
74+
makeSpiralMatrix(matrix, nextStartRowIdx, nextStartColIdx, nextDirectionOrder, result, visited);
75+
}
76+
}
77+
78+
79+

0 commit comments

Comments
 (0)