-
-
Notifications
You must be signed in to change notification settings - Fork 361
[seongmin36] WEEK 02 Solutions #2690
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
1912b25
b9fcfd4
10ff2ee
2aa8722
40d8496
29dfd91
96f2e5f
508b33d
c02aae1
075b911
9c61c8c
909ff53
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,41 @@ | ||
| /** | ||
| 중요한 것은 짝을 찾는 것이다. | ||
| 즉, 정수가 0이 되는 '역원(inverse)'을 찾아야 한다. | ||
| 역원을 담을 저장소가 필요한데, | ||
| 찾아야할 역원은 여러개일 필요가 없기 때문에 주머니 역할로 Set 인스턴스를 사용한다. | ||
| 중복 조건은 정렬된 배열에서 현재 인덱스보다 큰 원소 중에서 동일한 값을 제외한다. | ||
| */ | ||
| /** | ||
| * @param {number[]} nums | ||
| * @return {number[][]} | ||
| */ | ||
|
|
||
| function threeSum(nums) { | ||
| let result = []; | ||
|
|
||
| nums.sort((a, b) => a - b); | ||
|
|
||
| for (let i = 0; i < nums.length; i++) { | ||
| if (nums[i] > 0) break; | ||
|
|
||
| // 중복 제거 → i>0 이웃한 두 수가 일치하면 skip | ||
| if (i > 0 && nums[i] === nums[i - 1]) continue; | ||
|
|
||
| let pocket = new Set(); | ||
|
|
||
| for (let g = i + 1; g < nums.length; g++) { | ||
| let find_num = -(nums[i] + nums[g]); | ||
|
|
||
| if (pocket.has(find_num)) { | ||
| result.push([nums[i], find_num, nums[g]]); | ||
|
|
||
| // 중복 제거 → 정렬된 상태에서 같은 수가 나오면 shift | ||
| while (g + 1 < nums.length && nums[g] === nums[g + 1]) { | ||
| g++; | ||
| } | ||
| } | ||
| pocket.add(nums[g]); | ||
| } | ||
| } | ||
| 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. 🏷️ 알고리즘 패턴 분석
📊 시간/공간 복잡도 분석
피드백: 배열을 활용해 앞선 두 경우의 합으로 현재 경우의 수를 구한다. 개선 제안: 추가 공간 없이 상수 공간으로 구현할 수도 있다.
|
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,18 @@ | ||
| /** | ||
| * @param {number} n | ||
| * @return {number} | ||
| */ | ||
| function climbStairs(n) { | ||
| if (n <= 2) return n; | ||
|
|
||
| let arr = new Array(n + 1); | ||
|
|
||
| arr[0] = 1; | ||
| arr[1] = 2; | ||
|
|
||
| for (let i = 2; i < arr.length; i++) { | ||
| arr[i] = arr[i - 2] + arr[i - 1]; | ||
| } | ||
|
|
||
| return arr[n - 1]; | ||
| } |
|
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,34 @@ | ||
| /** | ||
| 문제의 핵심은 '어떻게 인덱스와 곱을 이중 반복문을 쓰지 않고 해결하느냐'다. 'Goal' → 시간 복잡도 : O(N) | ||
| 여기서 사용된 개념: 'Two Pointer' | ||
| Two Pointer? → '배열에서 순차적으로 접근해야 할 때 두 개의 점의 위치를 기록하면서 처리하는 알고리즘' | ||
| 이중 반복을 사용하지 않고, 각 인덱스를 순회하면서 answer[index]에 본인을 제외한 곱셈을 중첩시킨다. | ||
| 본인을 제외한 나머지 원소의 곱이기 때문에 left와 right로 나눠서 중첩된 곱셈을 다시 곱한다. | ||
| */ | ||
|
|
||
| /** | ||
| * @param {number[]} nums | ||
| * @return {number[]} | ||
| */ | ||
| function productExceptSelf(nums) { | ||
| let answer = new Array(nums.length).fill(1); | ||
|
|
||
| let left = 0; | ||
| let right = nums.length - 1; | ||
|
|
||
| let mul_left = 1; | ||
| let mul_right = 1; | ||
|
|
||
| while (left < nums.length && right >= 0) { | ||
| answer[left] *= mul_left; | ||
| mul_left *= nums[left]; // 자기 자신 제외 곱 | ||
|
|
||
| answer[right] *= mul_right; | ||
| mul_right *= nums[right]; | ||
|
|
||
| left++; | ||
| right--; | ||
| } | ||
|
|
||
| return answer; | ||
| } |
|
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. 🏷️ 알고리즘 패턴 분석
📊 시간/공간 복잡도 분석
피드백: 두 문자열의 길이가 다르면 바로 false를 반환하고, 한 문자열의 문자 카운트를 맵에 기록한 뒤 다른 문자열로 차감한다. 개선 제안: 알파벳 문자 제한이 있다면 고정 크기 배열로도 구현 가능하다.
|
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,31 @@ | ||
| /** | ||
| 결국 같아야 것은 string의 길이와 안에 들어간 각 character의 갯수다. | ||
| 즉, s와 t의 문자의 갯수와 같으면 된다. | ||
| map을 사용하여 key와 value자리에 각각 문자, 갯수를 받는다. | ||
| s와 t를 비교하며 해당하는 문자 갯수-1을 한다. | ||
| 각 key의 value를 문제없이 차감했다면 true를 반환. 그 외 false를 반환 | ||
| */ | ||
|
|
||
| /** | ||
| * @param {string} s | ||
| * @param {string} t | ||
| * @return {boolean} | ||
| */ | ||
| function isAnagram(s, t) { | ||
| if (s.length !== t.length) return false; | ||
|
|
||
| let map_s = new Map(); | ||
|
|
||
| for (let char of s) { | ||
| map_s.set(char, (map_s.get(char) || 0) + 1); | ||
| } | ||
|
|
||
| for (let char of t) { | ||
| if (!map_s.has(char) || map_s.get(char) === 0) { | ||
| return false; | ||
| } | ||
| map_s.set(char, map_s.get(char) - 1); | ||
| } | ||
|
|
||
| return true; | ||
| } |
|
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. 🏷️ 알고리즘 패턴 분석
📊 시간/공간 복잡도 분석
피드백: 재귀적으로 왼쪽은 min, 현재값, 오른쪽은 현재값, max로 탐색하며 조건 검사를 한다. 개선 제안: 깊이가 큰 트리에서 스택 오버플로우를 우려한다면 비재귀 DFS로 바꿀 수 있다.
|
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,32 @@ | ||
| /** | ||
| 이진 탐색 트리의 특징은 다음과 같다. | ||
| - 부모 노드를 기준으로 left는 부모보다 작은 수 | ||
| - 부모 노드를 기준으로 right는 부모보다 큰 수 | ||
| 이 문제에서 구하려는 것은 '주어진 트리가 이진 탐색 트리를 만족하는가?'이다 | ||
| 이는 재귀함수를 사용하여 깊이 우선 탐색(DFS)을 통해 해결할 수 있다. | ||
| 여기서 validate는 'BST'의 특징을 비교하는 함수인데, | ||
| validate()는 validate를 반환하면서 깊이 탐색하여 최종 참/거짓을 판별한다. | ||
| */ | ||
| /** | ||
| * Definition for a binary tree node. | ||
| * function TreeNode(val, left, right) { | ||
| * this.val = (val===undefined ? 0 : val) | ||
| * this.left = (left===undefined ? null : left) | ||
| * this.right = (right===undefined ? null : right) | ||
| * } | ||
| */ | ||
| /** | ||
| * @param {TreeNode} root | ||
| * @return {boolean} | ||
| */ | ||
| function isValidBST(root) { | ||
| function validate(p, min, max) { | ||
| if (p === null) return true; | ||
|
|
||
| if (p.val <= min || p.val >= max) return false; | ||
|
|
||
| return validate(p.left, min, p.val) && validate(p.right, p.val, max); | ||
| } | ||
|
|
||
| return validate(root, -Infinity, Infinity); | ||
| } |
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.
🏷️ 알고리즘 패턴 분석
📊 시간/공간 복잡도 분석
피드백: 정렬 후 외부 루프를 두고 내부에서 중복 제거를 위한 처리와 보조 집합(pocket)을 사용한다.
개선 제안: 현재 구현은 시간복잡도가 O(n^2)인 구조를 잘 따르고 있다. 중복 제거를 배열 인덱스 비교로도 가능하지만, Set 사용으로도 안정적이다.