-
-
Notifications
You must be signed in to change notification settings - Fork 335
시간/공간 복잡도 테스트용 PR (리뷰 불가능) #2543
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
base: main
Are you sure you want to change the base?
Changes from all commits
a3017d1
b49681c
6a86e71
545d5eb
85775d8
b65124b
e90637e
ab0e84f
542016d
2d709eb
667dfa1
21abc9a
b9d8216
87b6fc6
44a17b4
36555b1
cda9cd3
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,67 @@ | ||
| const Node = function() { | ||
| this.children = {}; | ||
| this.isEnd = false; | ||
| } | ||
|
|
||
| var WordDictionary = function() { | ||
| this.root = new Node(); | ||
| }; | ||
|
|
||
| /** | ||
| * @param {string} word | ||
| * @return {void} | ||
| */ | ||
| WordDictionary.prototype.addWord = function(word) { | ||
| let currentNode = this.root; | ||
|
|
||
| for (let char of word) { | ||
| if (!currentNode.children[char]) { | ||
| currentNode.children[char] = new Node(); | ||
| } | ||
| currentNode = currentNode.children[char]; | ||
| } | ||
|
|
||
| currentNode.isEnd = true; | ||
| }; | ||
|
|
||
| /** | ||
| * @param {string} word | ||
| * @return {boolean} | ||
| */ | ||
| WordDictionary.prototype.search = function(word) { | ||
| if (word === undefined) return false; | ||
| return this._search(this.root, word, 0); | ||
| }; | ||
|
|
||
| WordDictionary.prototype._search = function(node, word, index) { | ||
| if (index === word.length) { | ||
| return node.isEnd; | ||
| } | ||
|
|
||
| const char = word[index]; | ||
|
|
||
| if (char !== '.') { | ||
| const child = node.children[char]; | ||
| return child ? this._search(child, word, index + 1) : false; | ||
| } | ||
|
|
||
| for (const key in node.children) { | ||
| if (this._search(node.children[key], word, index + 1)) { | ||
| 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) | ||
| */ | ||
|
|
||
| // n: 단어수, m: 단어 길이 | ||
| // addWord: 시간 복잡도 O(m) | ||
| // search: 시간 복잡도 O(m^2) | ||
| // 공간 복잡도 O(n * m) |
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🏷️ 알고리즘 패턴 분석
📊 시간/공간 복잡도 분석
풀이 1:
|
| 유저 분석 | 실제 분석 | 결과 | |
|---|---|---|---|
| Time | O(n^4) | O(n) | ❌ |
| Space | O(n) | O(1) | ❌ |
피드백: 배열 크기만큼 모든 원소를 탐색하므로 시간 복잡도는 선형이며, 공간은 상수이다.
개선 제안: 이 방법은 배열 크기가 커질수록 비효율적이므로 이진 탐색 방법을 고려하는 것이 좋다.
풀이 2: findMin_naive — Time: ❌ O(n^6) → O(n) / Space: ✅ O(1) → O(1)
| 유저 분석 | 실제 분석 | 결과 | |
|---|---|---|---|
| Time | O(n^6) | O(n) | ❌ |
| Space | O(1) | O(1) | ✅ |
피드백: 단순 탐색으로 구현이 쉽지만, 최악의 경우 배열 전체를 탐색하므로 시간 복잡도는 선형이다.
개선 제안: 이진 탐색을 활용하는 방법이 더 효율적이다.
풀이 3: findMin — Time: ❌ O(n^2*logn) → O(log n) / Space: ✅ O(1) → O(1)
| 유저 분석 | 실제 분석 | 결과 | |
|---|---|---|---|
| Time | O(n^2*logn) | O(log n) | ❌ |
| Space | O(1) | O(1) | ✅ |
피드백: 이진 탐색을 통해 배열을 반으로 나누며 최소값을 찾기 때문에 시간 복잡도는 로그 시간이다.
개선 제안: 현재 구현이 적절해 보입니다.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,43 @@ | ||
| // math의 min을 이용하는 방법 | ||
| // tc: O(n^4) | ||
| // sc: 잘 몰랐는데 모든 요소를 함수 인자로 풀어 콜스택에 올린다 하여 O(n)이 된다고 함.. | ||
| // (대용량의 배열 시 maximum exceed 에러가 날 수 있음) | ||
| const findMin_use_math_min = function (nums) { | ||
| return Math.min(...nums); | ||
| }; | ||
|
|
||
| // 메서드를 사용하지 않은 풀이. | ||
| // tc: O(n^6) | ||
| // sc: O(1) | ||
| const findMin_naive = function (nums) { | ||
| let min = nums[0]; | ||
|
|
||
| for (let i = 1; i < nums.length; i++) { | ||
| if (nums[i] <= min) { | ||
| min = nums[i]; | ||
| break; | ||
| } | ||
| } | ||
|
|
||
| return min; | ||
| }; | ||
|
|
||
| // 시간복잡도를 문제의 요구사항에 맞도록 줄여본 풀이 | ||
| // tc: O(n^2*logn) | ||
| // sc: O(1) | ||
| const findMin = function (nums) { | ||
| let left = 0, | ||
| right = nums.length - 1; | ||
|
|
||
| while (left < right) { | ||
| let mid = Math.floor((left + right) / 2); | ||
|
|
||
| if (nums[mid] > nums[right]) { | ||
| left = mid + 1; | ||
| } else { | ||
| right = mid; | ||
| } | ||
| } | ||
|
|
||
| return nums[left]; | ||
| }; |
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🏷️ 알고리즘 패턴 분석
📊 시간/공간 복잡도 분석
피드백: 모든 노드와 간선을 탐색하므로 시간과 공간 복잡도는 노드와 간선 수에 비례한다. 개선 제안: 현재 구현이 적절해 보입니다.
|
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,38 @@ | ||
| export class Solution { | ||
| /** | ||
| * @param {number} n - number of nodes | ||
| * @param {number[][]} edges - undirected edges | ||
| * @return {boolean} | ||
| */ | ||
| validTree(n, edges) { | ||
| if (n === 0) return true; | ||
|
|
||
| // 인접 리스트 생성 | ||
| const adj = {}; | ||
| for (let i = 0; i < n; i++) { | ||
| adj[i] = []; | ||
| } | ||
| for (const [n1, n2] of edges) { | ||
| adj[n1].push(n2); | ||
| adj[n2].push(n1); | ||
| } | ||
|
|
||
| const visit = new Set(); | ||
|
|
||
| const dfs = (i, prev) => { | ||
| if (visit.has(i)) return false; | ||
|
|
||
| visit.add(i); | ||
|
|
||
| for (const j of adj[i]) { | ||
| if (j === prev) continue; | ||
| if (!dfs(j, i)) return false; | ||
| } | ||
|
|
||
| return true; | ||
| }; | ||
|
|
||
| return dfs(0, -1) && visit.size === n; | ||
| } | ||
| } | ||
|
|
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🏷️ 알고리즘 패턴 분석
📊 시간/공간 복잡도 분석
피드백: 모든 노드를 한 번씩 탐색하며, 방문 여부를 저장하는 데 공간이 필요하다. 개선 제안: 현재 구현이 적절해 보입니다.
|
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,32 @@ | ||
| /** | ||
| * Definition for singly-linked list. | ||
| * 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) | ||
| * } | ||
| * } | ||
| */ | ||
|
|
||
| /* | ||
| 리스트 노드를 저장하는 Map을 생성, 노드를 탐색하며 해당 Map에 노드를 저장하고 이미 있는 노드일 경우 true 리턴 | ||
|
|
||
| 시간복잡도 : O(N) - N은 리스트의 개수 | ||
| 공간복잡도 : O(N) - Map 객체 | ||
| */ | ||
|
|
||
| function hasCycle(head: ListNode | null): boolean { | ||
| const nodeMap = new Map<ListNode, boolean>() | ||
|
|
||
| while (head) { | ||
| if (nodeMap.get(head) === true) { | ||
| return true | ||
| } | ||
| nodeMap.set(head, true) | ||
| head = head.next | ||
| } | ||
|
|
||
| return false | ||
| } |
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🏷️ 알고리즘 패턴 분석
📊 시간/공간 복잡도 분석
피드백: 모든 셀에 대해 DFS를 수행하므로 시간과 공간 복잡도는 격자 크기에 비례한다. 개선 제안: 현재 구현이 적절해 보입니다.
|
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,79 @@ | ||
| /** | ||
| pacific에 닿을 수 있는 grid를 판별하는 이중 배열과 atlantic에 닿을 수 있는지를 판별하는 이중 배열을 생성한다. | ||
| pacific 배열은 r, c 중 하나라도 0일 경우 true값, | ||
| atlantic 배열은 r, c 중 하나라도 length값과 같을 경우 true값을 채운다 | ||
|
|
||
| 이후 r, c 탐색을 돌며 pacific/ atlantic true인 값이 있으면 dfs를 돌린다 | ||
| - 이전 heights값보다 크거나 같으면 true 처리, 인접한 셀을 또 dfs 탐색 | ||
|
|
||
| 두 배열값이 둘 다 true인 위치들을 리턴한다 | ||
|
|
||
| 시간복잡도 : O(M*N) - 순회 | ||
| */ | ||
|
|
||
| function pacificAtlantic(heights: number[][]): number[][] { | ||
| const m = heights.length | ||
| const n = heights[0].length | ||
| const result = [] | ||
| const pacificChecker = Array.from({ length: m }).map((el, idx) => { | ||
| if (idx === 0) { | ||
| return new Array(n).fill(true) | ||
| } else { | ||
| const arr = new Array(n).fill(false) | ||
| arr[0] = true | ||
| return arr | ||
| } | ||
| }) | ||
| const atlanticChecker = Array.from({ length: m }).map((el, idx) => { | ||
| if (idx === m - 1) { | ||
| return new Array(n).fill(true) | ||
| } else { | ||
| const arr = new Array(n).fill(false) | ||
| arr[n - 1] = true | ||
| return arr | ||
| } | ||
| }) | ||
|
|
||
| const dx = [0, 1, -1, 0] | ||
| const dy = [1, 0, 0, -1] | ||
|
|
||
| const search = (row, col, checker, stdValue) => { | ||
| const value = heights[row][col] | ||
| if (value < stdValue) return | ||
|
|
||
| checker[row][col] = true | ||
|
|
||
| for (let i = 0; i < 4; i++) { | ||
| const newRow = row + dx[i] | ||
| const newCol = col + dy[i] | ||
| if (newRow < 0 || newRow >= m) continue | ||
| if (newCol < 0 || newCol >= n) continue | ||
| if (checker[newRow][newCol]) continue | ||
|
|
||
| search(newRow, newCol, checker, value) | ||
| } | ||
| } | ||
|
|
||
| // dfs 탐색 | ||
| for (let i = 0; i < m; i++) { | ||
| for (let j = 0; j < n; j++) { | ||
| if (pacificChecker[i][j]) { | ||
| search(i, j, pacificChecker, heights[i][j]) | ||
| } | ||
| if (atlanticChecker[i][j]) { | ||
| search(i, j, atlanticChecker, heights[i][j]) | ||
| } | ||
| } | ||
| } | ||
|
|
||
| for (let i = 0; i < m; i++) { | ||
| for (let j = 0; j < n; j++) { | ||
| if (pacificChecker[i][j] && atlanticChecker[i][j]) { | ||
| result.push([i, j]) | ||
| } | ||
| } | ||
| } | ||
|
|
||
| //pacific, atlantic 모두 true인 인덱스배열 반환 | ||
| return result | ||
| } |
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🏷️ 알고리즘 패턴 분석
📊 시간/공간 복잡도 분석
피드백: 고정된 32비트 연산이므로 시간과 공간 복잡도는 상수이다. 개선 제안: 현재 구현이 적절해 보입니다. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,12 @@ | ||
| // TC: O(1) | ||
| // SC: O(1) | ||
| impl Solution { | ||
| pub fn reverse_bits(n: u32) -> u32 { | ||
| let mut res: u32 = 0; | ||
| for i in 0..32 { | ||
| let bit = (n >> i) & 1; | ||
| res += bit << (31 - i); | ||
| } | ||
| res | ||
| } | ||
| } |
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.
🏷️ 알고리즘 패턴 분석
📊 시간/공간 복잡도 분석
풀이 1:
WordDictionary.prototype.addWord— Time: O(m) / Space: O(n * m)피드백: 단어의 길이 m에 비례하는 시간 복잡도를 가지며, 모든 단어를 저장하는 데 공간이 단어 수 n과 단어 길이 m에 비례한다.
개선 제안: 현재 구현이 적절해 보입니다.
풀이 2:
WordDictionary.prototype.search— Time: O(n * m) / Space: O(m)피드백: 최악의 경우 '.'가 모든 문자에 대해 재귀 호출을 유발하여 시간 복잡도가 증가할 수 있지만, 평균적으로는 효율적이다.
개선 제안: 현재 구현이 적절해 보입니다.