-
-
Notifications
You must be signed in to change notification settings - Fork 245
[재호] WEEK 05 Solutions #438
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
Changes from 5 commits
Commits
Show all changes
6 commits
Select commit
Hold shift + click to select a range
211ac1b
solve: best time to buy and sell stock
wogha95 1e095f7
solve: group anagrams
wogha95 426802c
solve: 3sum
wogha95 857452b
solve: word break
wogha95 1c8afe9
solve: implement trie prefix tree
wogha95 8cf6255
solve: group anagrams
wogha95 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
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,60 @@ | ||
/** | ||
* TC: O(N^2) | ||
* SC: O(N) | ||
* | ||
* 풀이 | ||
* 2sum의 확장 문제 (nums[i] == nums[j] + nums[k]) | ||
* 2sum은 투포인터로 시간복잡도 O(N)을 만들기 위해 투포인터를 활용한다. | ||
*/ | ||
|
||
/** | ||
* @param {number[]} nums | ||
* @return {number[][]} | ||
*/ | ||
var threeSum = function (nums) { | ||
const result = []; | ||
const sortedNums = nums.sort((a, b) => a - b); | ||
|
||
// 3개 항의 합이 0이 될 수 없는 경우 | ||
if (sortedNums[0] > 0 || sortedNums[sortedNums.length - 1] < 0) { | ||
return []; | ||
} | ||
|
||
// 1. 순회를 하며 2sum의 target 값을 지정함 | ||
for (let index = 0; index < sortedNums.length - 2; ) { | ||
twoSum(index + 1, sortedNums[index]); | ||
// 3. 동일한 숫자를 제외하기 위해 순회 | ||
while (sortedNums[index] === sortedNums[index + 1]) { | ||
index += 1; | ||
} | ||
index += 1; | ||
} | ||
|
||
return result; | ||
|
||
function twoSum(startIndex, target) { | ||
let left = startIndex; | ||
let right = sortedNums.length - 1; | ||
|
||
// 2. 투포인터로 2sum이 target이 되는 경우를 찾기 위해 순회 | ||
while (left < right) { | ||
const sum = sortedNums[left] + sortedNums[right]; | ||
|
||
if (sum + target === 0) { | ||
result.push([target, sortedNums[left], sortedNums[right]]); | ||
} | ||
|
||
if (sum + target < 0) { | ||
while (sortedNums[left] === sortedNums[left + 1]) { | ||
left += 1; | ||
} | ||
left += 1; | ||
} else { | ||
while (sortedNums[right] === sortedNums[right - 1]) { | ||
right -= 1; | ||
} | ||
right -= 1; | ||
} | ||
} | ||
} | ||
}; |
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,22 @@ | ||
/** | ||
* TC: O(N) | ||
* SC: O(1) | ||
*/ | ||
|
||
/** | ||
* @param {number[]} prices | ||
* @return {number} | ||
*/ | ||
var maxProfit = function (prices) { | ||
let maximumProfit = 0; | ||
let minimumPrice = prices[0]; | ||
|
||
for (const price of prices) { | ||
// 매일 (그날까지의) 최소 구매가를 기록합니다. | ||
minimumPrice = Math.min(minimumPrice, price); | ||
// 최대 이익을 갱신합니다. | ||
maximumProfit = Math.max(maximumProfit, price - minimumPrice); | ||
} | ||
|
||
return maximumProfit; | ||
}; |
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,51 @@ | ||
/** | ||
* TC: O(N * S) | ||
* SC: O(N) | ||
* N: strs.length, S: strs[i].length | ||
* | ||
* 풀이 | ||
* 주어진 배열 strs의 각 원소의 키를 구해서 같은 원소끼리 묶어 정답을 찾는다. | ||
* 키 구하는 방법은 주어진 문자열의 사용된 알파벳 갯수이다. | ||
*/ | ||
|
||
/** | ||
* @param {string[]} strs | ||
* @return {string[][]} | ||
*/ | ||
var groupAnagrams = function (strs) { | ||
// 1. 키를 저장할 Map | ||
const keyMap = new Map(); | ||
|
||
for (const str of strs) { | ||
// 2. 키를 구해서 동일한 키면 같은 값(배열)에 추가한다. | ||
const key = generateKey(str); | ||
|
||
if (keyMap.has(key)) { | ||
keyMap.get(key).push(str); | ||
} else { | ||
keyMap.set(key, [str]); | ||
} | ||
} | ||
|
||
// 3. 키를 저장한 Map의 값들을 모아 정답을 반환한다. | ||
const result = []; | ||
|
||
for (const v of keyMap.values()) { | ||
result.push(v); | ||
} | ||
|
||
return result; | ||
|
||
// 키 구하는 함수 | ||
function generateKey(str) { | ||
// 각 알파벳이 몇개 등장했는지 기록할 배열 | ||
const usedCount = new Array(26).fill(0); | ||
|
||
for (const s of str) { | ||
// 아스키코드로 변환하여 index를 구한다. | ||
usedCount[s.charCodeAt() - 97] += 1; | ||
} | ||
|
||
return usedCount.join(","); | ||
} | ||
}; |
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,81 @@ | ||
function Node() { | ||
this.value = null; | ||
this.wordGraph = new Map(); | ||
} | ||
|
||
var Trie = function () { | ||
this.wordGraph = new Map(); | ||
}; | ||
|
||
/** | ||
* TC: O(W) | ||
* SC: O(W) | ||
* W: word.length | ||
*/ | ||
|
||
/** | ||
* @param {string} word | ||
* @return {void} | ||
*/ | ||
Trie.prototype.insert = function (word) { | ||
let pointer = this; | ||
for (const w of word) { | ||
if (!pointer.wordGraph.has(w)) { | ||
pointer.wordGraph.set(w, new Node()); | ||
} | ||
pointer = pointer.wordGraph.get(w); | ||
} | ||
pointer.value = word; | ||
}; | ||
|
||
/** | ||
* TC: O(W) | ||
* SC: O(1) | ||
* W: word.length | ||
*/ | ||
|
||
/** | ||
* @param {string} word | ||
* @return {boolean} | ||
*/ | ||
Trie.prototype.search = function (word) { | ||
let pointer = this; | ||
for (const w of word) { | ||
if (!pointer.wordGraph.has(w)) { | ||
return false; | ||
} else { | ||
pointer = pointer.wordGraph.get(w); | ||
} | ||
} | ||
return pointer.value === word; | ||
}; | ||
|
||
/** | ||
* TC: O(P) | ||
* SC: O(1) | ||
* P:prefix.length | ||
*/ | ||
|
||
/** | ||
* @param {string} prefix | ||
* @return {boolean} | ||
*/ | ||
Trie.prototype.startsWith = function (prefix) { | ||
let pointer = this; | ||
for (const p of prefix) { | ||
if (!pointer.wordGraph.has(p)) { | ||
return false; | ||
} else { | ||
pointer = pointer.wordGraph.get(p); | ||
} | ||
} | ||
return true; | ||
}; | ||
|
||
/** | ||
* Your Trie object will be instantiated and called as such: | ||
* var obj = new Trie() | ||
* obj.insert(word) | ||
* var param_2 = obj.search(word) | ||
* var param_3 = obj.startsWith(prefix) | ||
*/ |
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,82 @@ | ||
/** | ||
* TC: O(W * S) | ||
* 4번에서 W만큼 순회 * 메모이제이션 S | ||
* | ||
* SC: O(S) | ||
* queue 최대 S + visited 최대 S | ||
* | ||
* S: s.length, W: wordDict.length | ||
*/ | ||
|
||
/** | ||
* @param {string} s | ||
* @param {string[]} wordDict | ||
* @return {boolean} | ||
*/ | ||
var wordBreak = function (s, wordDict) { | ||
const queue = [0]; | ||
const visited = new Set(); | ||
|
||
while (queue.length) { | ||
const start = queue.shift(); | ||
// 1. 도착했다면 정답 반환 | ||
if (start === s.length) { | ||
return true; | ||
} | ||
// 2. 이미 방문한 경우 순회 방지 | ||
if (visited.has(start)) { | ||
continue; | ||
} | ||
|
||
// 3. 방문 표시 남기고 | ||
visited.add(start); | ||
// 4. wordDict의 word를 이용할 있는 경우 | ||
for (const word of wordDict) { | ||
if (s.slice(start, start + word.length) === word) { | ||
queue.push(start + word.length); | ||
} | ||
} | ||
} | ||
|
||
return false; | ||
}; | ||
|
||
/** | ||
* TC: O(W * S) | ||
* 2번에서 W만큼 순회 * 메모이제이션 S | ||
* | ||
* SC: O(S) | ||
* possibleS의 길이 S + dfs의 깊이는 최대 S | ||
* | ||
* S: s.length, W: wordDict.length | ||
*/ | ||
|
||
/** | ||
* @param {string} s | ||
* @param {string[]} wordDict | ||
* @return {boolean} | ||
*/ | ||
var wordBreak = function (s, wordDict) { | ||
// 1. S의 index번째 글자까지 wordDict 조합이 가능한지 표시하는 배열 | ||
const possibleS = new Array(s.length + 1).fill(false); | ||
|
||
dfs(0); | ||
|
||
return possibleS[s.length]; | ||
|
||
function dfs(start) { | ||
// 2. wordDict의 word를 이용할 있는 경우 | ||
for (const word of wordDict) { | ||
if (s.slice(start, start + word.length) === word) { | ||
// 3. 이미 조합 가능 표시가 있는 index의 경우 백트래킹 | ||
if (possibleS[start + word.length]) { | ||
return; | ||
} | ||
|
||
// 4. 조합 가능하다는 표시를 하고 다음 index로 재귀 | ||
possibleS[start + word.length] = true; | ||
dfs(start + word.length); | ||
} | ||
} | ||
} | ||
}; |
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.
S
가max(strs[i].length)
이면 더 명확할 것 같습니다! (평균으로 하는 것도 같구요)그리고 SC 도
O(N)
에서S
가 고려되지 않은 것 같습니다 확인 한 번 부탁드립니다~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.
확인 감사합니다. 반영했습니다!
SC에서 S가 고려되지 않은 이유는
usedCount
에서 26개의 고정 배열을 사용하기 때문입니다!