-
-
Notifications
You must be signed in to change notification settings - Fork 305
[radiantchoi] WEEK 07 Solutions #2225
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
+179
−0
Merged
Changes from all commits
Commits
Show all changes
5 commits
Select commit
Hold shift + click to select a range
bfd741f
reverse linked list solution
radiantchoi 9699ecd
number of islands solution
radiantchoi 771d129
set matrix zeroes solutions
radiantchoi 4c72385
longest substring without repeating characters solution
radiantchoi aa2d942
unique paths solution
radiantchoi File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
30 changes: 30 additions & 0 deletions
30
longest-substring-without-repeating-characters/radiantchoi.py
This file contains hidden or 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,30 @@ | ||
| class Solution: | ||
| def lengthOfLongestSubstring(self, s: str) -> int: | ||
| # 문자열 전체를 순회, 서브스트링이란 서로 붙어 있는 문자열 | ||
| # 글자를 볼 때 현재 모아둔 글자 모음에 중복 글자가 있다면? | ||
| # 일단 지금까지의 길이 업데이트 | ||
| # 중복된 글자가 등장한 인덱스 체크 | ||
| # 현재 모아둔 문자열의 길이에서 해당 인덱스까지의 "머리"를 덜어내고 지금 보는 문자를 더해서, 서브스트링을 이어나감 | ||
|
|
||
| current = {} | ||
| tuning = 0 | ||
| result = 0 | ||
|
|
||
| for (index, letter) in enumerate(s): | ||
| if current.get(letter, index) < index: | ||
| result = max(result, len(current)) | ||
|
|
||
| tail_of_head = current[letter] | ||
|
|
||
| new_current = {} | ||
| for key in current: | ||
| if current[key] > tail_of_head: | ||
| new_current[key] = current[key] | ||
|
|
||
| current = new_current | ||
|
|
||
| current[letter] = index | ||
|
|
||
| result = max(result, len(current)) | ||
|
|
||
| return result |
This file contains hidden or 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,40 @@ | ||
| class Solution { | ||
| func numIslands(_ grid: [[Character]]) -> Int { | ||
| var grid = grid | ||
| var result = 0 | ||
|
|
||
| for i in 0..<grid.count { | ||
| for j in 0..<grid[0].count { | ||
| // 임의의 인덱스 i, j에 대해 탐색 수행 | ||
| // 서로 떨어져 있는 섬도 모두 찾기 위해 | ||
| var isIsland = false | ||
| traverse(i, j, &grid, &isIsland) | ||
|
|
||
| if isIsland { | ||
| result += 1 | ||
| } | ||
| } | ||
| } | ||
|
|
||
| return result | ||
| } | ||
|
|
||
| // DFS 함수 | ||
| func traverse(_ row: Int, _ col: Int, _ grid: inout [[Character]], _ isIsland: inout Bool) { | ||
| // 인덱스가 유효한지 검사하고 유효하지 않으면 함수 종료 | ||
| guard (0..<grid.count) ~= row && (0..<grid[0].count) ~= col else { return } | ||
|
|
||
| // 이미 방문한 곳, 원래 바다인 곳 등의 이유로 유효하지 않은 면적이면 함수 종료 | ||
| guard grid[row][col] != "0" else { return } | ||
|
|
||
| // 방문 표시 + 유효한 면적을 발견했으므로 "섬이다" 라고 인정 | ||
| grid[row][col] = "0" | ||
| isIsland = true | ||
|
|
||
| // 상하좌우 탐색 - 한 번의 콜 스택에서 유효한 모든 연결된 면적을 찾아서 방문 표시 | ||
| traverse(row+1, col, &grid, &isIsland) | ||
| traverse(row-1, col, &grid, &isIsland) | ||
| traverse(row, col+1, &grid, &isIsland) | ||
| traverse(row, col-1, &grid, &isIsland) | ||
| } | ||
| } |
This file contains hidden or 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,24 @@ | ||
| // 문제에서 주어진 ListNode | ||
| class ListNode { | ||
| val: number | ||
| next: ListNode | null | ||
|
|
||
| constructor(val?: number, next?: ListNode | null) { | ||
| this.val = (val===undefined ? 0 : val) | ||
| this.next = (next===undefined ? null : next) | ||
| } | ||
| } | ||
|
|
||
| function reverseList(head: ListNode | null): ListNode | null { | ||
| let current = null; | ||
|
|
||
| // 매번 새로운 노드를 생성하고, 지금까지 순회한 모든 결과를 이 새로운 노드의 next로 연결 | ||
| while (head !== null) { | ||
| const newNode = new ListNode(head.val); | ||
| newNode.next = current; | ||
| current = newNode; | ||
| head = head.next; | ||
| } | ||
|
|
||
| return current; | ||
| }; | ||
This file contains hidden or 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,75 @@ | ||
| class Solution { | ||
| func setZeroes(_ matrix: inout [[Int]]) { | ||
| // 원래 0이었던 것의 주변을 모두 0으로 만들되, 기존에 0이었던 것들은 독립적으로 영향력을 행사해야 함 | ||
| // 주변으로 먼저 0으로 만들어 버리면, flood fill 형태로 모든 원소가 0이 되어버림 | ||
| // 따라서 변경해야 할 값을 미리 "마크해 두고", 이후 이 마크해 둔 값을 0으로 바꾸는 전략 선택 | ||
|
|
||
| // 원소 값의 범위: -2^31보다 크거나 같고, 2^31 - 1보다 작거나 같음 | ||
| // 따라서 범위에 포함되지 않는 2^32를 사용하여 계산 - 일부 언어에서는 overflow 발생 가능 | ||
| let threshold = Int(pow(2.0, 32)) | ||
|
|
||
| for i in 0..<matrix.count { | ||
| for j in 0..<matrix[i].count { | ||
| if matrix[i][j] == 0 { | ||
| // 상, 하, 좌, 우를 각각 전담해 마크하는 함수들 | ||
| // 해당하는 자리의 중복 조회를 줄이기 위해 각각의 인덱스에 미리 튜닝을 가해서 투입 | ||
| traverseRowNegative(i-1, j, &matrix, threshold) | ||
| traverseRowPositive(i+1, j, &matrix, threshold) | ||
| traverseColumnNegative(i, j-1, &matrix, threshold) | ||
| traverseColumnPositive(i, j+1, &matrix, threshold) | ||
| } | ||
| } | ||
| } | ||
|
|
||
| // 전체 매트릭스를 순회하면서 마크해뒀던 값을 0으로 치환 | ||
| for i in 0..<matrix.count { | ||
| for j in 0..<matrix[i].count { | ||
| if matrix[i][j] == threshold { | ||
| matrix[i][j] = 0 | ||
| } | ||
| } | ||
| } | ||
| } | ||
|
|
||
| func traverseRowNegative(_ row: Int, _ col: Int, _ matrix: inout [[Int]], _ threshold: Int) { | ||
| guard (0..<matrix.count) ~= row else { return } | ||
|
|
||
| // 이미 0이었던 원소라면 건드리지 말고, 그렇지 않다면 threshold로 마크 | ||
| // 아래 모든 함수에서도 동일한 원리로 동작 | ||
| if matrix[row][col] != 0 { | ||
| matrix[row][col] = threshold | ||
| } | ||
|
|
||
| traverseRowNegative(row - 1, col, &matrix, threshold) | ||
| } | ||
|
|
||
| func traverseRowPositive(_ row: Int, _ col: Int, _ matrix: inout [[Int]], _ threshold: Int) { | ||
| guard (0..<matrix.count) ~= row else { return } | ||
|
|
||
| if matrix[row][col] != 0 { | ||
| matrix[row][col] = threshold | ||
| } | ||
|
|
||
| traverseRowPositive(row + 1, col, &matrix, threshold) | ||
| } | ||
|
|
||
| func traverseColumnNegative(_ row: Int, _ col: Int, _ matrix: inout [[Int]], _ threshold: Int) { | ||
| guard (0..<matrix[row].count) ~= col else { return } | ||
|
|
||
| if matrix[row][col] != 0 { | ||
| matrix[row][col] = threshold | ||
| } | ||
|
|
||
| traverseColumnNegative(row, col - 1, &matrix, threshold) | ||
| } | ||
|
|
||
| func traverseColumnPositive(_ row: Int, _ col: Int, _ matrix: inout [[Int]], _ threshold: Int) { | ||
| guard (0..<matrix[row].count) ~= col else { return } | ||
|
|
||
| if matrix[row][col] != 0 { | ||
| matrix[row][col] = threshold | ||
| } | ||
|
|
||
| traverseColumnPositive(row, col + 1, &matrix, threshold) | ||
| } | ||
| } |
This file contains hidden or 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,10 @@ | ||
| import math | ||
|
|
||
| class Solution: | ||
| def uniquePaths(self, m: int, n: int) -> int: | ||
| # 도착을 위해 실제로 움직여야 하는 칸은 아래로 (m - 1)칸, 오른쪽으로 (n - 1)칸 | ||
| # 총 (m + 1) + (n + 1)칸을 움직여야 하는데, 이만큼의 "빈 바구니"가 있다고 가정 | ||
| # 빈 바구니의 몇 번 박스에 오른쪽으로 가기/아래로 가기를 넣을 것인가? 의 문제 | ||
| # 조합을 통해 둘 중 아무거나를 바구니에 넣는 경우의 수를 구하면, 나머지 칸에 나머지 하나를 다 넣을 수 있다. | ||
| # 따라서 math.comb(m + n - 2, n - 1)도 동일한 결과 반환 | ||
| return math.comb(m + n - 2, m - 1) |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
새로운 노드를 생성하는 것도 좋지만 기존 노드의 next를 변경하는 방식도 있습니다!
그런데 이게 어떻게 보면 직관적이긴 하네요 ㅎㅎ
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
네 저도 리뷰를 하다 보니까, 참조를 바꾸는 방식으로 푸신 분들이 제법 있었습니다! 아무래도 그쪽 방식이 정석인 것 같은데, 이건 제가 참조가 오락가락하다 보니 헷갈려서 직관적으로 풀겠다 하는 의향이 강하게 반영되지 않았나 생각합니다ㅋㅋ