Skip to content

Commit 58386e4

Browse files
Merge pull request #1409 from YoungSeok-Choi/feature/week-6
[YoungSeok-Choi] week 6 solutions
2 parents 2560589 + ae12971 commit 58386e4

File tree

6 files changed

+462
-10
lines changed

6 files changed

+462
-10
lines changed
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
// tc: O(n)
2+
// 투 포인터라는 문제풀이 방법으로 간단히 (답지보고) 해결...
3+
class Solution {
4+
public int maxArea(int[] h) {
5+
int start = 0;
6+
int end = h.length - 1;
7+
int mx = -987654321;
8+
9+
while(start < end) {
10+
mx = Math.max(mx, (end - start) * Math.min(h[start], h[end]));
11+
12+
if(h[start] < h[end]) {
13+
start++;
14+
} else {
15+
end--;
16+
}
17+
}
18+
19+
return mx;
20+
}
21+
}
22+
23+
24+
// 예외처리가 덕지덕지 붙기 시작할 때. (잘못됨을 깨닫고)다른 방법으로 풀어햐 하는건 아닌지 생각하는 습관 필요함..ㅠ
25+
class WrongSolution {
26+
public int maxArea(int[] h) {
27+
int mx = Math.min(h[0], h[1]);
28+
int idx = 0;
29+
30+
for(int i = 1; i < h.length; i++) {
31+
int offset = i - idx;
32+
33+
int prevCalc = Math.min(h[i - 1], h[i]);
34+
int calc = Math.min(h[idx], h[i]);
35+
int newMx = calc * offset;
36+
37+
// 새롭게 인덱스를 바꿔버리는게 더 나을때.
38+
if(prevCalc > newMx) {
39+
idx = i - 1;
40+
mx = Math.max(mx, prevCalc);
41+
continue;
42+
}
43+
44+
// 물을 더 많이 담을 수 있을 때.
45+
if(h[idx] < h[i] && newMx > mx) {
46+
if(i == 2) {
47+
int exc = Math.min(h[1], h[i]) * offset;
48+
if(exc > newMx) {
49+
idx = 1;
50+
mx = Math.max(exc, mx);
51+
continue;
52+
}
53+
}
54+
55+
idx = i;
56+
}
57+
58+
mx = Math.max(newMx, mx);
59+
}
60+
61+
return mx;
62+
}
63+
}
Lines changed: 170 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,170 @@
1+
import java.util.ArrayList;
2+
import java.util.HashMap;
3+
import java.util.List;
4+
import java.util.Map;
5+
6+
7+
// NOTE: dot에 대한 wildcard 검색이 핵심이었던 문제.
8+
// NOTE: tc -> 문자 입력 O(n), 패턴검색 O(26^n), 패턴X검색 O(1)
9+
10+
/**
11+
검색어 | 의미
12+
"." | 길이가 1인 아무 문자와 매치
13+
".a" | 길이 2: 첫 글자는 아무 문자, 두 번째는 a
14+
"..d" | 길이 3: 처음 두 글자는 아무 문자, 마지막은 d
15+
"..." | 길이 3인 모든 단어와 매치
16+
*/
17+
class WordDictionary {
18+
19+
private WordDictionary[] child;
20+
private Character val;
21+
private Map<String, Boolean> cMap;
22+
23+
public WordDictionary() {
24+
this.cMap = new HashMap<>();
25+
this.val = null;
26+
}
27+
28+
public void addWord(String word) {
29+
if(this.cMap.containsKey(word)) return;
30+
31+
this.cMap.put(word, true);
32+
this.innerInsert(word);
33+
}
34+
35+
public void innerInsert(String word) {
36+
if(word.length() == 0) return;
37+
38+
if(this.child == null) {
39+
this.child = new WordDictionary[26];
40+
}
41+
42+
char c = word.charAt(0);
43+
int idx = c - 97;
44+
45+
if(this.child[idx] == null) {
46+
this.child[idx] = new WordDictionary();
47+
this.child[idx].val = c;
48+
}
49+
50+
this.child[idx].innerInsert(word.substring(1));
51+
}
52+
53+
public boolean search(String word) {
54+
if(!word.contains(".")) return this.cMap.containsKey(word);
55+
56+
57+
return this.patternSearch(word);
58+
}
59+
60+
private boolean patternSearch(String wildcard) {
61+
if(wildcard.length() == 0) return true;
62+
63+
char c = wildcard.charAt(0);
64+
if(c == '.') { // NOTE: wildcard를 만났을 때, 해당 depth는 검사하지 않고, 다음 번(자식) 문자들에 대해서 검색 이어나가기.
65+
List<Boolean> res = new ArrayList<>();
66+
67+
for(WordDictionary children : this.child) {
68+
if(children != null) {
69+
res.add(children.patternSearch(wildcard.substring(1)));
70+
}
71+
}
72+
73+
for(boolean b : res) {
74+
if(b) return true;
75+
}
76+
77+
return false;
78+
}
79+
80+
int idx = c - 97;
81+
if(this.child == null || this.child[idx] == null || this.child[idx].val == null) return false;
82+
83+
return this.child[idx].patternSearch(wildcard.substring(1));
84+
}
85+
}
86+
87+
/**
88+
* Your WordDictionary object will be instantiated and called as such:
89+
* WordDictionary obj = new WordDictionary();
90+
* obj.addWord(word);
91+
* boolean param_2 = obj.search(word);
92+
*/
93+
94+
95+
// 이전 TRIE 자료구조를 모른 채로 풀이했던 문제..
96+
class PrevWordDictionary {
97+
98+
private String word;
99+
private PrevWordDictionary leftChild;
100+
private PrevWordDictionary rightChild;
101+
102+
public PrevWordDictionary() {
103+
this.leftChild = null;
104+
this.rightChild = null;
105+
this.word = null;
106+
}
107+
108+
public void addWord(String word) {
109+
if(this.word == null) {
110+
this.word = word;
111+
return;
112+
}
113+
114+
// NOTE: 사전 순으로 크고 작음을 두어 이진처리.
115+
if(this.word.compareTo(word) == 1) {
116+
117+
this.rightChild = new PrevWordDictionary();
118+
this.rightChild.addWord(word);
119+
} else if (this.word.compareTo(word) == -1) {
120+
121+
this.leftChild = new PrevWordDictionary();
122+
this.leftChild.addWord(word);
123+
} else {
124+
// already exists. just return
125+
}
126+
}
127+
128+
public boolean search(String word) {
129+
if(word.contains(".")) {
130+
// String replaced = word.replace(".", "");
131+
132+
// return word.startsWith(".") ? this.startsWith(replaced) : this.endsWith(replaced);
133+
return this.patternSearch(word.replace(".", ""));
134+
}
135+
136+
if(this.word == null) {
137+
return false;
138+
}
139+
140+
if(this.word.equals(word)) {
141+
return true;
142+
}
143+
144+
if(this.rightChild == null && this.leftChild == null) {
145+
return false;
146+
}
147+
148+
if(this.word.compareTo(word) == 1) {
149+
return this.rightChild == null ? false : this.rightChild.search(word);
150+
} else {
151+
return this.leftChild == null ? false : this.leftChild.search(word);
152+
}
153+
}
154+
155+
private boolean patternSearch(String wildcard) {
156+
if(this.word.contains(wildcard)) return true;
157+
158+
boolean left = false;
159+
boolean right = false;
160+
if(this.leftChild != null) {
161+
left = this.leftChild.patternSearch(wildcard);
162+
}
163+
164+
if(this.rightChild != null) {
165+
right = this.rightChild.patternSearch(wildcard);
166+
}
167+
168+
return left || right;
169+
}
170+
}
Lines changed: 72 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,63 @@
11
import java.util.HashMap;
22
import java.util.Map;
33

4-
// Map으로 풀려버려서 당황..
5-
// 이진트리? 어떤식으로 풀어야 할지 자료구조 정하고 다시 풀어보기..
4+
// 한 글자씩 잘라서 하위 자식 노드들로 관리
5+
// search 동작은 기존 그대로 Map자료구조에서 찾고, 이후 prefix연산에서 속도를 개선 (230ms -> 30ms)
66
class Trie {
77

8-
Map<String, Boolean> tMap;
8+
private Trie[] child;
9+
private Character val;
10+
private Map<String, Boolean> cMap;
911

1012
public Trie() {
11-
this.tMap = new HashMap<>();
13+
this.cMap = new HashMap<>();
14+
this.val = null;
1215
}
1316

1417
public void insert(String word) {
15-
this.tMap.put(word, true);
18+
if(this.cMap.containsKey(word)) return;
19+
20+
this.cMap.put(word, true);
21+
this.innerInsert(word);
22+
}
23+
24+
public void innerInsert(String word) {
25+
if(word.length() == 0) return;
26+
27+
if(this.child == null) {
28+
this.child = new Trie[26];
29+
}
30+
31+
char c = word.charAt(0);
32+
int idx = c - 97;
33+
34+
if(this.child[idx] == null) {
35+
this.child[idx] = new Trie();
36+
this.child[idx].val = c;
37+
}
38+
39+
this.child[idx].innerInsert(word.substring(1));
1640
}
1741

1842
public boolean search(String word) {
19-
return this.tMap.containsKey(word);
43+
return this.cMap.containsKey(word);
2044
}
45+
46+
// public boolean search(String word) {
47+
48+
// }
2149

22-
public boolean startsWith(String prefix) {
23-
for(String key : this.tMap.keySet()) {
24-
if(key.startsWith(prefix)) return true;
50+
public boolean startsWith(String word) {
51+
if(word.length() == 0) {
52+
return true;
2553
}
2654

27-
return false;
55+
char c = word.charAt(0);
56+
int idx = c - 97;
57+
if(this.child == null || this.child[idx] == null || this.child[idx].val == null) return false;
58+
59+
60+
return this.child[idx].startsWith(word.substring(1));
2861
}
2962
}
3063

@@ -35,3 +68,32 @@ public boolean startsWith(String prefix) {
3568
* boolean param_2 = obj.search(word);
3669
* boolean param_3 = obj.startsWith(prefix);
3770
*/
71+
72+
73+
// Map으로 풀려버려서 당황..
74+
// 이진트리? 어떤식으로 풀어야 할지 자료구조 정하고 다시 풀어보기..
75+
class BeforeTrie {
76+
77+
Map<String, Boolean> tMap;
78+
79+
public BeforeTrie() {
80+
this.tMap = new HashMap<>();
81+
}
82+
83+
public void insert(String word) {
84+
this.tMap.put(word, true);
85+
}
86+
87+
public boolean search(String word) {
88+
return this.tMap.containsKey(word);
89+
}
90+
91+
public boolean startsWith(String prefix) {
92+
for(String key : this.tMap.keySet()) {
93+
if(key.startsWith(prefix)) return true;
94+
}
95+
96+
return false;
97+
}
98+
}
99+

0 commit comments

Comments
 (0)