-
Notifications
You must be signed in to change notification settings - Fork 126
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #902 from ekgns33/main
[byteho0n] Week 6
- Loading branch information
Showing
5 changed files
with
348 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
/* | ||
input : array of integer height | ||
output : maximum amount of water a container can store. | ||
we can build container with two different line (height[i], height[j] when i < j) | ||
example | ||
1 8 6 2 5 4 8 3 7 | ||
choose i = 1. | ||
choose j = 4 | ||
8 ______5 | ||
amount of water == (j - i) * min(height[i], height[j]) | ||
= 3 * 5 = 15 | ||
we have to maximize amount of water. | ||
constraints: | ||
1) is the input array valid? | ||
length of array is in range [2, 10^5] | ||
2) positive integers? | ||
no. range of height is [0, 10 ^4] | ||
>> check amount can be overflow. 10^4 * 10 ^ 5 = 10^9 < Integer range | ||
edge: | ||
1) if length is 2 | ||
return min(height[0], height[1]). | ||
... | ||
solution 1) brute force; | ||
iterate through the array from index i = 0 to n-1 | ||
when n is the length of input array | ||
iterate through the array from index j = i + 1 to n; | ||
calculate the amount of water and update max amount | ||
ds : array | ||
algo : x | ||
tc : O(n^2) ~= 10^10 TLE | ||
space : O(1) | ||
solution 2) better | ||
ds : array | ||
algo: two pointer? | ||
two variant for calculating amount of water | ||
1. height 2. width | ||
set width maximum at first, check heights | ||
decrease width one by one | ||
- at each step width is maximum. | ||
so we have to maximize | ||
the minimum between left and right pointer | ||
use left and right pointer | ||
while left < right | ||
calculate amount | ||
compare | ||
if height[left] < height[right] | ||
move left by one | ||
else | ||
vice versa | ||
return max | ||
tc : O(n) | ||
sc : O(1) | ||
*/ | ||
class Solution { | ||
public int maxArea(int[] height) { | ||
int left = 0; | ||
int right = height.length - 1; | ||
int maxAmount = 0; | ||
while(left < right) { | ||
int curAmount = (right - left) * Math.min(height[left], height[right]); | ||
maxAmount = Math.max(maxAmount, curAmount); | ||
if(height[left] < height[right]) { | ||
left++; | ||
} else { | ||
right--; | ||
} | ||
} | ||
return maxAmount; | ||
} | ||
} |
109 changes: 109 additions & 0 deletions
109
design-add-and-search-words-data-structure/ekgns33.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,109 @@ | ||
/** | ||
design ds that supports add, find | ||
find if string matches any previously added string. | ||
>> some kind of dictionary | ||
example | ||
add bad | ||
add dad | ||
add mad | ||
search pad >> false | ||
search bad >> true | ||
search .ad >> true . can be 'b' or 'd' or 'm' | ||
search b.. >> true .. can be "ad" | ||
constraints: | ||
1) empty string can be valid input? | ||
nope. lenght of string is in range of [1, 25] | ||
2) string only contiains alphanumeric? or alphabet | ||
only lowercase English letters | ||
3) how many queries can be given as input? | ||
at most 10^4 | ||
solution 1) brute force | ||
save to data structure. for add | ||
check every character for all the saved words | ||
O(kn) when k is the number of saved words, | ||
n is the length of input word token | ||
25 * 25 * 10^4 | ||
tc : O(kn) + O(kn) | ||
add : O(1) | ||
search : O(kn) | ||
sc : O(kn) | ||
solution 2) trie? | ||
save words to trie. | ||
when searching | ||
do bfs or backtracking dfs | ||
if current charcter is . add all childs | ||
else add matching childs | ||
overall tc : O(sum(m)) + O(n), | ||
add : O(m), when m is the length of saved word | ||
search : O(n), when n is the length of searh word | ||
sc : O(sum(m)) | ||
if volume of search query is much bigger than add query | ||
trie solution would be better | ||
O(n) search time vs O(mn) search time | ||
*/ | ||
class WordDictionary { | ||
class TrieNode { | ||
TrieNode[] childs; | ||
boolean isEnd; | ||
TrieNode() { | ||
childs = new TrieNode[26]; | ||
isEnd = false; | ||
} | ||
} | ||
TrieNode root; | ||
public WordDictionary() { | ||
root = new TrieNode(); | ||
} | ||
|
||
public void addWord(String word) { | ||
TrieNode curNode = root; | ||
for(char c : word.toCharArray()) { | ||
if(curNode.childs[c-'a'] == null) { | ||
curNode.childs[c-'a'] = new TrieNode(); | ||
} | ||
curNode = curNode.childs[c-'a']; | ||
} | ||
curNode.isEnd = true; | ||
} | ||
|
||
public boolean search(String word) { | ||
return dfsHelper(root, word, 0); | ||
} | ||
|
||
public boolean dfsHelper(TrieNode node, String word, int p) { | ||
//end clause | ||
if(p == word.length()) { | ||
return node.isEnd; | ||
} | ||
|
||
char curC = word.charAt(p); | ||
if(curC == '.') { | ||
for(TrieNode next : node.childs) { | ||
if(next != null) { | ||
if(dfsHelper(next, word, p + 1)) return true; | ||
} | ||
} | ||
return false; | ||
} else { | ||
if(node.childs[curC-'a'] != null) { | ||
if(dfsHelper(node.childs[curC - 'a'], word, p + 1)) return true; | ||
} | ||
return false; | ||
} | ||
|
||
|
||
} | ||
} | ||
|
||
/** | ||
* Your WordDictionary object will be instantiated and called as such: | ||
* WordDictionary obj = new WordDictionary(); | ||
* obj.addWord(word); | ||
* boolean param_2 = obj.search(word); | ||
*/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
/** | ||
input : array of integers | ||
output : length of the longest strictly increasing subsequence; | ||
example | ||
0 1 0 3 2 3 > 0 1 2 3 >> length : 4 | ||
4 3 2 1 > 1 >> length : 1 | ||
1 1 1 1 > 1 >> length : 1 | ||
constraints : | ||
1) empty array allowed? | ||
no, at least one | ||
solution 1) brute force | ||
nested for loop | ||
iterate through the array from index i = 0 to n-1 when n is the lenght of input | ||
iterate throught the array from index j = i + 1 to n | ||
update current Maximum value | ||
if bigger than prev max value count ++ | ||
tc : O(n^2); | ||
sc : O(1) | ||
solution 2) binary search + dp | ||
iterate through the array | ||
search from saved values. | ||
if current value is bigger than everything add | ||
else change value | ||
let val[i] save the smallest value of length i subsequence | ||
tc : O(nlogn) | ||
sc : O(n) | ||
*/ | ||
|
||
class Solution { | ||
public int lengthOfLIS(int[] nums) { | ||
List<Integer> vals = new ArrayList<>(); | ||
for(int num : nums) { | ||
if(vals.isEmpty() || vals.getLast() < num) { | ||
vals.add(num); | ||
} else { | ||
vals.set(binarySearch(vals, num), num); | ||
} | ||
} | ||
return vals.size(); | ||
} | ||
int binarySearch(List<Integer> vals, int num) { | ||
int l = 0, r = vals.size()-1; | ||
while(l <= r) { | ||
int mid = (r - l) / 2+ l; | ||
if(vals.get(mid) == num) { | ||
return mid; | ||
} else if (vals.get(mid) > num) { | ||
r = mid - 1; | ||
} else { | ||
l = mid + 1; | ||
} | ||
} | ||
return l; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
/* | ||
*. lr -> | ||
* ^ 1 2 3 4. rd | ||
* lu 5 6 7 8. v | ||
* <- rl | ||
* tc : O(mn) | ||
* sc : O(1) | ||
* */ | ||
|
||
class Solution { | ||
public List<Integer> spiralOrder(int[][] matrix) { | ||
int m = matrix.length; | ||
int n = matrix[0].length; | ||
int lr = 0, rd = 0, rl = n -1, lu = m - 1; | ||
int cnt = 0, target = m*n; | ||
List<Integer> res = new ArrayList<>(); | ||
|
||
while(lr <= rl && rd <= lu) { | ||
for(int startLeft = lr; startLeft <= rl; startLeft++) { | ||
res.add(matrix[rd][startLeft]); | ||
} | ||
rd++; | ||
for(int startUp = rd; startUp <=lu; startUp++) { | ||
res.add(matrix[startUp][rl]); | ||
} | ||
rl--; | ||
if(rd <= lu) { | ||
for(int startRight = rl; startRight >= lr; startRight--) { | ||
res.add(matrix[lu][startRight]); | ||
} | ||
} | ||
lu--; | ||
if(lr <= rl) { | ||
for(int startDown = lu; startDown >= rd; startDown--) { | ||
res.add(matrix[startDown][lr]); | ||
} | ||
} | ||
lr++; | ||
} | ||
return res; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
/** | ||
input : string s contains just (, ), {, }, [, ] | ||
output : return if s is valid | ||
valid means that parentheses are matched(balanced) | ||
example | ||
((())) : valid | ||
(((())) : invalid | ||
{() : invalid | ||
constraint : | ||
1) input string can be empty string? | ||
nope. at least one character >> if length is odd number return false | ||
edge: | ||
1) if the length of string is odd number return false | ||
solution 1) | ||
ds : stack | ||
algo : x | ||
iterate through the string s | ||
if opening bracket, add to stack | ||
else check the top element of stack | ||
if matched pop | ||
else return false; | ||
return false | ||
tc : O(n) | ||
sc : O(n) worst case : every character is opening bracket | ||
*/ | ||
class Solution { | ||
public boolean isValid(String s) { | ||
//edge | ||
if(s.length() % 2 == 1) return false; | ||
// we can use deque instead | ||
Stack<Character> stack = new Stack<>(); | ||
|
||
for(char c : s.toCharArray()) { | ||
if(c == '(' || c == '{' || c == '[') { | ||
stack.push(c); | ||
} else { | ||
if(stack.isEmpty()) return false; | ||
if(c == ')') { | ||
if(stack.peek() != '(') return false; | ||
} else if (c == '}') { | ||
if(stack.peek() != '{') return false; | ||
} else if (c == ']'){ | ||
if(stack.peek() != '[') return false; | ||
} | ||
stack.pop(); | ||
} | ||
} | ||
return stack.isEmpty(); | ||
} | ||
} |