Skip to content

[byteho0n] Week 6 #902

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Jan 18, 2025
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
83 changes: 83 additions & 0 deletions container-with-most-water/ekgns33.java
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 design-add-and-search-words-data-structure/ekgns33.java
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);
*/
60 changes: 60 additions & 0 deletions longest-increasing-subsequence/ekgns33.java
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;
}
}
42 changes: 42 additions & 0 deletions spiral-matrix/ekgns33.java
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;
}
}
54 changes: 54 additions & 0 deletions valid-parentheses/ekgns33.java
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();
}
}
Loading