-
-
Notifications
You must be signed in to change notification settings - Fork 195
[강희찬] Week1 문제 풀이 #307
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
[강희찬] Week1 문제 풀이 #307
Changes from all commits
2ee18ce
b300fb0
f1eee0e
9517d44
0cac7f6
5b4f429
535930e
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,21 @@ | ||
/** | ||
217. Contains Duplicate | ||
|
||
Example 1: | ||
Input: nums = [1,2,3,1] | ||
Output: true | ||
|
||
Example 2: | ||
Input: nums = [1,2,3,4] | ||
Output: false | ||
|
||
Example 3: | ||
Input: nums = [1,1,1,3,3,4,3,2,4,2] | ||
Output: true | ||
*/ | ||
|
||
// Time complexity: O(n) | ||
// Space complexity: O(n) | ||
function containsDuplicate(nums: number[]): boolean { | ||
return nums.length !== new Set(nums).size; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
/* | ||
230. Kth Smallest Element in a BST | ||
|
||
Example 1: | ||
3 | ||
/ \ | ||
1 4 | ||
\ | ||
2 | ||
Input: root = [3,1,4,null,2], k = 1 | ||
Output: 1 | ||
|
||
Example 2: | ||
5 | ||
/ \ | ||
3 6 | ||
/ \ | ||
2 4 | ||
/ | ||
1 | ||
Input: root = [5,3,6,2,4,null,null,1], k = 3 | ||
Output: 3 | ||
*/ | ||
|
||
// class TreeNode { | ||
// val: number | ||
// left: TreeNode | null | ||
// right: TreeNode | null | ||
// constructor(val?: number, left?: TreeNode | null, right?: TreeNode | null) { | ||
// this.val = (val===undefined ? 0 : val) | ||
// this.left = (left===undefined ? null : left) | ||
// this.right = (right===undefined ? null : right) | ||
// } | ||
// } | ||
|
||
// Time complexity: O(n) | ||
// Space complexity: O(n) | ||
function kthSmallest(root: TreeNode | null, k: number): number { | ||
function inorder(root: TreeNode | null, arr: number[]) { | ||
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. arr의 params가 꼭 필요한 함수인지 궁금합니다. 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. 아 그렇네요. 스코프 내의 함수이니 별도로 인자로 전달해주지 않아도 정상적으로 동작 했을것 같습니다! |
||
if (!root) return; | ||
|
||
inorder(root.left, arr); | ||
arr.push(root.val); | ||
inorder(root.right, arr); | ||
} | ||
|
||
const arr: number[] = []; | ||
inorder(root, arr); | ||
return arr[k - 1]; | ||
} | ||
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. 필수 사항은 아니지만 k번째 왔을 때 early return하여 순회를 멈추는 방법도 생각해보는건 어떨까요? 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. 그렇네요 확실히 얼리 리턴을 해 주니 성능이 올라가네요! 감사합니다~ |
||
|
||
/** | ||
* NOT MY SOLUTION - NO NEED TO REVIEW | ||
* Awesome solution from leetcode | ||
*/ | ||
function kthSmallest(root: TreeNode | null, k: number): number { | ||
/* | ||
define. return the kth smallest value in a BST. | ||
assess. smallest value can be 0. At least k nodes, which can be at its smallest, 1. | ||
approach. DFS with backtracking. Traverse down the left edges until we hit null. if k is 1, return that value. Else, backtrack, go right, then try to go left again. Use a stack. | ||
*/ | ||
const stack = []; | ||
|
||
let currentRank = 0; | ||
|
||
let currentNode = root; | ||
|
||
while (currentNode || stack.length > 0) { | ||
|
||
while (currentNode) { | ||
stack.push(currentNode); | ||
|
||
currentNode = currentNode.left; | ||
} | ||
|
||
currentNode = stack.pop(); | ||
|
||
currentRank++; | ||
|
||
if (currentRank === k) return currentNode.val; | ||
|
||
currentNode = currentNode.right; | ||
} | ||
|
||
}; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
/** | ||
191. Number of 1 Bits | ||
|
||
Example 1: | ||
Input: n = 11 | ||
Output: 3 | ||
Explanation: | ||
The input binary string 1011 has a total of three set bits. | ||
|
||
Example 2: | ||
Input: n = 128 | ||
Output: 1 | ||
Explanation: | ||
The input binary string 10000000 has a total of one set bit. | ||
|
||
Example 3: | ||
Input: n = 2147483645 | ||
Output: 30 | ||
Explanation: | ||
The input binary string 1111111111111111111111111111101 has a total of thirty set bits. | ||
*/ | ||
|
||
function hammingWeight(n: number): number { | ||
// Time complexity: O(logn) | ||
// Space complexity: O(logn) | ||
// it has a better readability and not so bad in space complexity | ||
return n.toString(2).split('1').length - 1; | ||
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. string 메서드 관련 시간복잡도는 모르고있었는데 리뷰하면서 알게됐네요 :) |
||
|
||
// Time complexity: O(logn) | ||
// Space complexity: O(1) | ||
// it's better in space complexity, but sometimes the bitwise operation is not easy to understand | ||
let count = 0; | ||
while (n !== 0) { | ||
count += n & 1; | ||
n >>>= 1; | ||
} | ||
return count; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
/* | ||
647. Palindromic Substrings | ||
|
||
Example 1: | ||
Input: s = "abc" | ||
Output: 3 | ||
Explanation: Three palindromic strings: "a", "b", "c". | ||
|
||
Example 2: | ||
Input: s = "aaa" | ||
Output: 6 | ||
Explanation: Six palindromic strings: "a", "a", "a", "aa", "aa", "aaa". | ||
*/ | ||
|
||
// Time complexity: O(n^3) | ||
// Space complexity: O(n^3) | ||
function countSubstrings(s: string): number { | ||
function isPalindrome(s: string): boolean { | ||
if (s.length === 0) return false; | ||
if (s.length === 1) return true; | ||
let left = 0; | ||
let right = s.length - 1; | ||
while (left < right) { | ||
if (s[left] !== s[right]) return false; | ||
left++; | ||
right--; | ||
} | ||
return true; | ||
} | ||
|
||
const candidates = new Map<string, number>(); | ||
for (let i = 0; i < s.length; i++) { | ||
for (let j = i + 1; j <= s.length; j++) { | ||
// this will cost both t.c. and s.c. O(n^3) | ||
candidates.set(s.slice(i, j), (candidates.get(s.slice(i, j)) || 0) + 1); | ||
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. slice method을 중심으로 생각해보면 필수적으로 get 메서드를 사용해야 할까요? 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. 질문의 내용을 정확하게 이해하지 못했습니다 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. �질문이 이상했네요. 저는 candidates를 Map 객체가 아닌 문자 배열로 할당하는 방법이 더 명시적이라고 생각합니다. 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. 오 이런.. 왜 문자열이 나올거라고 착각했을까요? |
||
} | ||
} | ||
|
||
let count = 0; | ||
for (const [key, value] of candidates) { | ||
if (isPalindrome(key)) count += value | ||
} | ||
|
||
return count; | ||
}; | ||
|
||
// Time complexity: O(n^3) | ||
// Space complexity: O(1) | ||
function countSubstrings(s: string): number { | ||
function isPalindrome(s: string): boolean { | ||
if (s.length === 0) return false; | ||
if (s.length === 1) return true; | ||
let left = 0; | ||
let right = s.length - 1; | ||
while (left < right) { | ||
if (s[left] !== s[right]) return false; | ||
left++; | ||
right--; | ||
} | ||
return true; | ||
} | ||
|
||
let count = 0; | ||
for (let i = 0; i < s.length; i++) { | ||
for (let j = i + 1; j <= s.length; j++) { | ||
// this will cause t.c. O(n^3). need to optimize this part | ||
if (isPalindrome(s.slice(i, j))) count++; | ||
} | ||
} | ||
|
||
return count; | ||
} | ||
|
||
// Time complexity: O(n^2) | ||
// Space complexity: O(1) | ||
function countSubstrings(s: string): number { | ||
function expandIsPalindrome(left: number, right: number): number { | ||
let count = 0; | ||
while (left >= 0 && right < s.length && s[left] === s[right]) { | ||
count++; | ||
left--; | ||
right++; | ||
} | ||
return count; | ||
Comment on lines
+77
to
+84
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. 이런 방법을 사용하면 모두 순회를 할 수 있군요..! |
||
} | ||
|
||
let count = 0; | ||
for (let i = 0; i < s.length; i++) { | ||
count += expandIsPalindrome(i, i); | ||
count += expandIsPalindrome(i, i + 1); | ||
} | ||
return count; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
/* | ||
347. Top K Frequent Elements | ||
|
||
Example 1: | ||
Input: nums = [1,1,1,2,2,3], k = 2 | ||
Output: [1,2] | ||
|
||
Example 2: | ||
Input: nums = [1], k = 1 | ||
Output: [1] | ||
*/ | ||
|
||
// Time complexity: O(nlogn) | ||
// Space complexity: O(n) | ||
function topKFrequent(nums: number[], k: number): number[] { | ||
const frequentMap = new Map<number, number>(); | ||
for (const num of nums) { // s.c. O(n) | ||
frequentMap.set(num, (frequentMap.get(num) || 0) + 1); | ||
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. 현재 코드에서 || 연산자의 사용에서는 문제 없지만 ??연산자를 활용하는것이 목적에 맞아보이는데 희찬님은 어떻게 생각하시나요? 저는 ||연산자의 경우 boolean 값을 반환하는 경우가 있어 예기치 못한 실수나 오류가 발생할 확률이 있을것이라고 생각합니다. 그래서 값을 반환하고 싶으면 ?? 연산자를 통해서 왼쪽 피연산자가 falsy한 값일 때 지정한 값으로 반환하는게 휴면에러를 줄일수 있을것 같아요. 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. 음 습관적으로 그리고 |
||
} | ||
return Array.from(frequentMap.entries()) | ||
.sort((a, b) => b[1] - a[1]) // this will cost t.c. O(nlogn) | ||
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. 이번 주에 아직 시간이 많이 남았으니 |
||
.slice(0, k) | ||
.map((v) => v[0]); | ||
} |
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.
set의 속성을 잘 활용하시네요. 이런방법이 있는지 몰랐네요👍