Skip to content

Commit 0d7115a

Browse files
authored
Merge pull request #2538 from sadie100/main
[sadie100] WEEK7 Solutions
2 parents 9541315 + f08f147 commit 0d7115a

5 files changed

Lines changed: 201 additions & 0 deletions

File tree

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
/*
2+
words를 맵형태로 저장, 각 스펠링과 다음에 나오는 문자열을 key-value로 하는 맵으로 저장
3+
.의 경우 모든 경우를 탐색한다
4+
5+
시간복잡도 :
6+
addWord : O(L) (L은 words의 길이)
7+
search : 일반적으로 O(L), .이 많으면 O(26^k) (k는 .의 개수)
8+
9+
*/
10+
class TrieNode {
11+
children: Map<string, TrieNode>
12+
isEnd: boolean
13+
14+
constructor() {
15+
this.children = new Map()
16+
this.isEnd = false
17+
}
18+
}
19+
20+
class WordDictionary {
21+
words = new TrieNode()
22+
constructor() {}
23+
24+
addWord(word: string): void {
25+
let curWords = this.words
26+
27+
for (let i = 0; i < word.length; i++) {
28+
const char = word[i]
29+
30+
if (!curWords.children.has(char)) {
31+
curWords.children.set(char, new TrieNode())
32+
}
33+
34+
curWords = curWords.children.get(char)
35+
}
36+
curWords.isEnd = true
37+
}
38+
39+
search(word: string): boolean {
40+
return this.searchRecursively(word, this.words)
41+
}
42+
43+
searchRecursively(word: string, area: TrieNode) {
44+
for (let i = 0; i < word.length; i++) {
45+
if (!area) return false
46+
const char = word[i]
47+
48+
if (char === '.') {
49+
const values = [...area.children.values()]
50+
51+
for (let newArea of values) {
52+
const result = this.searchRecursively(word.slice(i + 1), newArea)
53+
if (result) return true
54+
}
55+
return false
56+
} else {
57+
if (!area.children.has(char)) return false
58+
area = area.children.get(char)
59+
}
60+
}
61+
62+
if (area.isEnd) return true
63+
return false
64+
}
65+
}
66+
67+
/**
68+
* Your WordDictionary object will be instantiated and called as such:
69+
* var obj = new WordDictionary()
70+
* obj.addWord(word)
71+
* var param_2 = obj.search(word)
72+
*/
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
/*
2+
투 포인터 start와 end 생성, end를 1씩 증가하며 s를 탐색한다
3+
각 문자열의 마지막 위치를 기록하는 locate Map을 생성한다
4+
end값이 locate에 이미 존재하는데 start가 해당값+1보다 작을 경우, start를 해당값+1로 변경하고 locate를 업데이트, 이어서 탐색한다
5+
매번 탐색마다 최대 길이 result를 갱신한다
6+
7+
시간복잡도 : O(N) - 단일 순회
8+
공간복잡도 : O(N) (locate Map)
9+
10+
11+
*/
12+
13+
function lengthOfLongestSubstring(s: string): number {
14+
let start = 0
15+
let end = 0
16+
const locate = new Map()
17+
let result = 0
18+
19+
while (end < s.length) {
20+
let char = s[end]
21+
if (locate.has(char)) {
22+
start = Math.max(start, locate.get(char) + 1)
23+
}
24+
locate.set(char, end)
25+
result = Math.max(result, end - start + 1)
26+
end += 1
27+
}
28+
29+
return result
30+
}

number-of-islands/sadie100.ts

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
/*
2+
m x n visited 이중배열을 만들고 grid를 탐색,
3+
visited false면서 1값이 있는 타일이 있으면 dfs로 상하좌우를 탐색, visited true로 만든 뒤 result+=1한다
4+
탐색이 마치면 result를 리턴한다
5+
6+
시간복잡도 : O(M + N)
7+
공간복잡도 : O(M + N) - visited
8+
*/
9+
10+
const dx = [0, 1, -1, 0]
11+
const dy = [1, 0, 0, -1]
12+
13+
function numIslands(grid: string[][]): number {
14+
const visited = Array.from({ length: grid.length }, () =>
15+
new Array(grid[0].length).fill(false),
16+
)
17+
let result = 0
18+
19+
function search(row: number, col: number) {
20+
visited[row][col] = true
21+
22+
for (let i = 0; i < 4; i++) {
23+
const newRow = row + dx[i]
24+
const newCol = col + dy[i]
25+
26+
if (newRow < 0 || newRow >= grid.length) continue
27+
if (newCol < 0 || newCol >= grid[0].length) continue
28+
29+
if (visited[newRow][newCol] === false && grid[newRow][newCol] === '1') {
30+
search(newRow, newCol)
31+
}
32+
}
33+
}
34+
35+
for (let i = 0; i < grid.length; i++) {
36+
for (let j = 0; j < grid[0].length; j++) {
37+
if (visited[i][j] === false && grid[i][j] === '1') {
38+
search(i, j)
39+
result += 1
40+
}
41+
}
42+
}
43+
44+
return result
45+
}

reverse-linked-list/sadie100.ts

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
/**
2+
* Definition for singly-linked list.
3+
* class ListNode {
4+
* val: number
5+
* next: ListNode | null
6+
* constructor(val?: number, next?: ListNode | null) {
7+
* this.val = (val===undefined ? 0 : val)
8+
* this.next = (next===undefined ? null : next)
9+
* }
10+
* }
11+
*/
12+
13+
/*
14+
직전 노드를 담는 변수 before과 다음 노드를 담는 변수 next, 순회중인 노드 head 변수와 함께 list를 순회
15+
head의 next에 before을 넣고, head를 next로 변환하며 head가 null이 아닐 때까지 반복한다
16+
17+
시간복잡도 : O(N) - 1번 순회
18+
공간복잡도 : O(1) - before, next 변수
19+
20+
*/
21+
function reverseList(head: ListNode | null): ListNode | null {
22+
if (!head) return head
23+
let originNext = head.next
24+
let before = null
25+
26+
while (head !== null) {
27+
originNext = head.next
28+
head.next = before
29+
before = head
30+
head = originNext
31+
}
32+
33+
return before
34+
}

unique-paths/sadie100.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
/*
2+
dp 배열 생성, top-left에서 bottom-right로 이동하며 위 값, 왼쪽 값을 더하며 dp를 업데이트, 마지막 원소를 리턴한다
3+
4+
시간복잡도 : O(m * n)
5+
*/
6+
7+
const dx = [0, 1]
8+
const dy = [1, 0]
9+
10+
function uniquePaths(m: number, n: number): number {
11+
const dp = Array.from({ length: m }, () => new Array(n).fill(1))
12+
13+
for (let i = 1; i < m; i++) {
14+
for (let j = 1; j < n; j++) {
15+
dp[i][j] = dp[i - 1][j] + dp[i][j - 1]
16+
}
17+
}
18+
19+
return dp[m - 1][n - 1]
20+
}

0 commit comments

Comments
 (0)