Skip to content
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

[강희찬] WEEK 6 Solution #468

Merged
merged 5 commits into from
Sep 20, 2024
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
21 changes: 21 additions & 0 deletions container-with-most-water/HC-kang.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/**
* https://leetcode.com/problems/container-with-most-water/
* T.C. O(n)
* S.C. O(1)
*/
function maxArea(height: number[]): number {
let [res, i, j] = [0, 0, height.length - 1];

while (i < j) {
const volume = Math.min(height[i], height[j]) * (j - i);
res = Math.max(res, volume);

if (height[i] < height[j]) {
i++;
} else {
j--;
}
}

return res;
}
102 changes: 102 additions & 0 deletions design-add-and-search-words-data-structure/HC-kang.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
/**
* https://leetcode.com/problems/design-add-and-search-words-data-structure
*/
// Using Trie
class WordDictionary {
constructor(private root: Record<string, any> = {}) {}

/**
* T.C. O(L) L: length of a word
* S.C. O(L)
*/
addWord(word: string): void {
let node = this.root;
for (const char of word) {
if (!node[char]) {
node[char] = {};
}
node = node[char];
}
node['isEnd'] = true;
}

/**
* T.C. O(N) - there are only 2 dots in the word(26 * 26 * N)
* S.C. O(N * L) N: number of words, L: length of a word
*/
search(word: string): boolean {
return this.dfs(word, this.root);
}

private dfs(word: string, node: Record<string, any>): boolean {
for (let i = 0; i < word.length; i++) {
if (word[i] === '.') {
for (const key in node) {
if (this.dfs(word.slice(i + 1), node[key])) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

string을 slice하는 로직은 그 길이만큼 시간 복잡도를 먹어서, 그 대신 index를 파라미터로 받아서 �시간복잡도를 개선할 수도 있습니다

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

오 그렇게 할 수 있겠네요. 감사합니다~!

return true;
}
}
return false;
}
if (!node[word[i]]) {
return false;
}
node = node[word[i]];
}
return !!node['isEnd'];
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

오 js, ts 에는 이중부정(!!) 이란 게 있네요 여기에서 undefined 인 경우를 방지하기 위함이군요 ㅋㅋ 새롭네용 ㅎㅎㅎ

}
}

// Using Array and Set
class WordDictionary {
constructor(
private words: Set<string>[] = Array.from({ length: 25 }, () => new Set())
) {}

/**
* T.C. O(1)
* S.C. O(N * L)
*/
addWord(word: string): void {
this.words[word.length - 1].add(word);
}

/**
* T.C. O(N * L) N: number of words, L: length of a word
* S.C. O(1)
*/
search(word: string): boolean {
const hasDot = word.indexOf('.') !== -1;
const set = this.words[word.length - 1];

if (!hasDot) {
return set.has(word);
}

for (const w of set) {
let i = 0;
while (i < word.length) {
if (word[i] == '.') {
i++;
continue;
}
if (word[i] !== w[i]) {
break;
}
i++;
}

if (i === word.length) {
return true;
}
}
return false;
}
}

/**
* Your WordDictionary object will be instantiated and called as such:
* var obj = new WordDictionary()
* obj.addWord(word)
* var param_2 = obj.search(word)
*/
32 changes: 32 additions & 0 deletions longest-increasing-subsequence/HC-kang.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/**
* https://leetcode.com/problems/longest-increasing-subsequence
* T.C. O(nlogn)
* S.C. O(n)
*/
function lengthOfLIS(nums: number[]): number {
const sub: number[] = [];

function findSlot(num: number): number {
let left = 0;
let right = sub.length - 1;

while (left <= right) {
const mid = Math.floor((left + right) / 2);
if (sub[mid] < num) {
left = mid + 1;
} else {
right = mid - 1;
}
}

return left;
}

for (let i = 0; i < nums.length; i++) {
const num = nums[i];
const slot = findSlot(num);
sub[slot] = num;
}

return sub.length;
}
44 changes: 44 additions & 0 deletions spiral-matrix/HC-kang.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/**
* https://leetcode.com/problems/spiral-matrix
* T.C. O(m * n)
* S.C. O(m * n)
*/
function spiralOrder(matrix: number[][]): number[] {
const clockwise = [
[0, 1],
[1, 0],
[0, -1],
[-1, 0],
];
let currentDirection = 0;

const visited = new Array(matrix.length)
.fill(0)
.map(() => new Array(matrix[0].length).fill(false));

const result: number[] = [];

let row = 0;
let col = 0;

while (result.length < matrix.length * matrix[0].length) {
result.push(matrix[row][col]);
visited[row][col] = true;

const nextRow = row + clockwise[currentDirection][0];
const nextCol = col + clockwise[currentDirection][1];

if (
nextRow < 0 || nextRow >= matrix.length ||
nextCol < 0 || nextCol >= matrix[0].length ||
visited[nextRow][nextCol]
) {
currentDirection = (currentDirection + 1) % 4;
}

row += clockwise[currentDirection][0];
col += clockwise[currentDirection][1];
}

return result;
}
17 changes: 17 additions & 0 deletions valid-parentheses/HC-kang.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
/**
* https://leetcode.com/problems/valid-parentheses
* T.C. O(n)
* S.C. O(n)
*/
function isValid(s: string): boolean {
const pairs: Record<string, string> = { '{': '}', '[': ']', '(': ')' };
const stack: string[] = [];

if (s.length % 2 == 1) return false;

for (const char of s) {
if (pairs[char]) stack.push(char);
else if (char != pairs[stack.pop()!]) return false;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

안녕하세요~ 희찬님!

!= 와 !==, == 와 ===를 혼용하시는 이유가 따로 있을까요?
저는 개인적으로 얕은 비교(==, !=)의 동작을 신경쓰지 않고 엄격한 비교만 일관적으로 하기 위해 깊은 비교를 사용하는 것을 선호하고 권장하는 편이에요.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@sounmind 네 안녕하세요~ 저도 말씀하신 내용에 동의합니다.
최근 레거시 코드베이스에서 작업중이라 ==와 !=를 자주 사용하다 보니 습관적으로 얕은 비교를 사용하는 경우가 많아졌네요
덕분에 좀 더 의식하고 사용 할 수 있을 것 같습니다!

}
return !stack.length;
}