-
-
Notifications
You must be signed in to change notification settings - Fork 360
[ICE0208] WEEK 02 solutions #2680
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
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,54 @@ | ||
| import java.util.*; | ||
|
|
||
| class Solution { | ||
| public List<List<Integer>> threeSum(int[] nums) { | ||
| /* | ||
| * 세 수의 합이 0이 되는 조합을 찾는다. | ||
| * | ||
| * nums[i]를 하나 고정하면, | ||
| * 나머지 두 수를 찾는 Two Sum 문제로 바꿀 수 있다. | ||
| * | ||
| * seen에는 현재 i 기준으로 지나온 값들을 저장한다. | ||
| * target이 seen에 있으면 nums[i] + target + nums[j] = 0 이다. | ||
| * | ||
| * | ||
| * 시간 복잡도: O(n^2) | ||
| * 공간 복잡도: O(n) | ||
| */ | ||
|
|
||
| Arrays.sort(nums); | ||
|
|
||
| List<List<Integer>> answer = new ArrayList<>(); | ||
|
|
||
| for (int i = 0; i < nums.length; i++) { | ||
| // 같은 기준값은 한 번만 사용 | ||
| if (i > 0 && nums[i] == nums[i - 1]) { | ||
| continue; | ||
| } | ||
|
|
||
| // 기준값이 양수면 합이 0이 될 수 없음 | ||
| if (nums[i] > 0) { | ||
| break; | ||
| } | ||
|
|
||
| Set<Integer> seen = new HashSet<>(); | ||
|
|
||
| for (int j = i + 1; j < nums.length; j++) { | ||
| int target = -nums[i] - nums[j]; | ||
|
|
||
| if (seen.contains(target)) { | ||
| answer.add(Arrays.asList(nums[i], target, nums[j])); | ||
|
|
||
| // 같은 nums[j]는 중복 조합을 만들 수 있으므로 스킵 | ||
| while (j + 1 < nums.length && nums[j] == nums[j + 1]) { | ||
| j++; | ||
| } | ||
| } | ||
|
|
||
| seen.add(nums[j]); | ||
| } | ||
| } | ||
|
|
||
| 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. 🏷️ 알고리즘 패턴 분석
📊 시간/공간 복잡도 분석
피드백: 두 변수만으로 이차식 점화식을 순회하며 필요한 값을 얻는다. 배열 전체를 사용하지 않아 공간을 절약한다. 개선 제안: 현재 구현이 적절해 보입니다.
|
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,35 @@ | ||
| class Solution { | ||
| public int climbStairs(int n) { | ||
| /* | ||
| * i번째 계단에 도착하는 경우는 두 가지다. | ||
| * | ||
| * 1. i - 1번째 계단에서 한 칸 올라오는 경우 | ||
| * 2. i - 2번째 계단에서 두 칸 올라오는 경우 | ||
| * | ||
| * dp[i]를 i번째 계단에 도착하는 방법의 수라고 하면, | ||
| * dp[i] = dp[i - 1] + dp[i - 2] 이다. (i >= 3) | ||
| * | ||
| * 이때 dp[i]를 구하기 위해 필요한 값은 직전 값과 전전 값뿐이다. | ||
| * 따라서 dp 배열 전체를 만들지 않고 prev1, prev2 두 변수만 사용해 갱신한다. | ||
| * | ||
| * 시간 복잡도: O(n) | ||
| * 공간 복잡도: O(1) | ||
| */ | ||
|
|
||
| if (n <= 2) { | ||
| // 1번째 계단은 1가지, 2번째 계단은 2가지 방법으로 오를 수 있다. | ||
| return n; | ||
| } | ||
|
|
||
| int prev2 = 1; // dp[1] | ||
| int prev1 = 2; // dp[2] | ||
|
|
||
| for (int i = 3; i <= n; i++) { | ||
| int curr = prev1 + prev2; // dp[i] | ||
| prev2 = prev1; | ||
| prev1 = curr; | ||
| } | ||
|
|
||
| return prev1; | ||
| } | ||
| } |
|
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 @@ | ||
| class Solution { | ||
| public int[] productExceptSelf(int[] nums) { | ||
| /* | ||
| * 자기 자신을 제외한 모든 요소의 곱 | ||
| * = 왼쪽 요소들의 곱 * 오른쪽 요소들의 곱 | ||
| * | ||
| * 왼쪽에서 오른쪽으로 순회하면서 누적 곱을 구하면 | ||
| * 각 요소 기준 왼쪽 요소들의 곱을 구할 수 있다. | ||
| * | ||
| * 반대로 오른쪽에서 왼쪽으로 순회하면서 누적 곱을 구하면 | ||
| * 각 요소 기준 오른쪽 요소들의 곱을 구할 수 있다. | ||
| * | ||
| * 왼쪽 요소들의 곱과 오른쪽 요소들의 곱을 곱하면 정답이 된다. | ||
| * | ||
| * 시간 복잡도: O(n) | ||
| * 공간 복잡도: O(1) | ||
| * 단, 반환 배열 result는 제외한다. | ||
| */ | ||
| int n = nums.length; | ||
| int[] result = new int[n]; | ||
|
|
||
| // 각 위치 기준 왼쪽 요소들의 곱을 result에 저장 | ||
| int prefixProduct = 1; | ||
| for (int i = 0; i < n; i++) { | ||
| result[i] = prefixProduct; | ||
| prefixProduct *= nums[i]; | ||
| } | ||
|
|
||
| // 각 위치 기준 오른쪽 요소들의 곱을 result에 반영 | ||
| int suffixProduct = 1; | ||
| for (int i = n - 1; i >= 0; i--) { | ||
| result[i] *= suffixProduct; | ||
| suffixProduct *= nums[i]; | ||
| } | ||
|
|
||
| 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,25 @@ | ||
| import java.util.Arrays; | ||
|
|
||
| class Solution { | ||
| /** | ||
| * n = s.length(), m = t.length() | ||
| * 각 문자열에서 알파벳별 등장 횟수를 센 뒤 비교한다. | ||
| * 시간 복잡도: O(n + m) | ||
| * 공간 복잡도: O(1) - 알파벳 소문자 26개만 사용하기 때문 | ||
| */ | ||
| public boolean isAnagram(String s, String t) { | ||
| // 0: a, 1: b, ... , 25: z | ||
| int[] sCount = new int[26]; | ||
| int[] tCount = new int[26]; | ||
|
|
||
| for (int i = 0; i < s.length(); i++) { | ||
| sCount[s.charAt(i) - 'a']++; | ||
| } | ||
|
|
||
| for (int i = 0; i < t.length(); i++) { | ||
| tCount[t.charAt(i) - 'a']++; | ||
| } | ||
|
|
||
| return Arrays.equals(sCount, tCount); | ||
| } | ||
| } |
|
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,28 @@ | ||
| from collections import Counter | ||
|
|
||
|
|
||
| class Solution_2: | ||
| def isAnagram(self, s: str, t: str) -> bool: | ||
| """ | ||
| n = len(s), m = len(t) | ||
|
|
||
| 두 문자열의 각 문자 개수를 센 뒤 비교한다. | ||
|
|
||
| 시간 복잡도: O(n + m) | ||
| 공간 복잡도: O(1) | ||
| - 입력 문자가 알파벳 소문자 26개로 제한되기 때문 | ||
| """ | ||
| return Counter(s) == Counter(t) | ||
|
|
||
|
|
||
| class Solution_01: | ||
| def isAnagram(self, s: str, t: str) -> bool: | ||
| """ | ||
| n = len(s), m = len(t) | ||
|
|
||
| 두 문자열을 각각 정렬한 뒤 비교한다. | ||
|
|
||
| 시간 복잡도: O(n log n + m log m) | ||
| 공간 복잡도: O(n + m) | ||
| """ | ||
| return sorted(s) == sorted(t) |
|
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,37 @@ | ||
| class Solution { | ||
| /* | ||
| * 현재 노드가 허용된 범위 안에 있는지 확인한다. | ||
| * | ||
| * 왼쪽 자식은 현재 노드보다 작아야 하므로, | ||
| * upperBound를 현재 노드 값으로 줄인다. | ||
| * | ||
| * 오른쪽 자식은 현재 노드보다 커야 하므로, | ||
| * lowerBound를 현재 노드 값으로 올린다. | ||
| * | ||
| * 시간 복잡도: O(n) | ||
| * - n은 전체 노드의 개수 | ||
| * - 모든 노드를 한 번씩 검사한다. | ||
| * | ||
| * 공간 복잡도: O(h) | ||
| * - h는 트리의 높이 | ||
| * - 재귀 호출 스택이 현재 탐색 중인 경로만큼 쌓인다. | ||
| * - 균형 잡힌 트리라면 O(log n) / 한쪽으로 치우친 트리라면 O(n) | ||
| */ | ||
| private boolean isValidWithinRange(TreeNode node, long lowerBound, long upperBound) { | ||
| if (node == null) { | ||
| return true; | ||
| } | ||
|
|
||
| // BST는 중복 값을 허용하지 않으므로 경계값과 같아도 false다. | ||
| if (node.val <= lowerBound || node.val >= upperBound) { | ||
| return false; | ||
| } | ||
|
|
||
| return isValidWithinRange(node.left, lowerBound, node.val) | ||
| && isValidWithinRange(node.right, node.val, upperBound); | ||
| } | ||
|
|
||
| public boolean isValidBST(TreeNode root) { | ||
| return isValidWithinRange(root, Long.MIN_VALUE, Long.MAX_VALUE); | ||
| } | ||
| } |
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.
🏷️ 알고리즘 패턴 분석
📊 시간/공간 복잡도 분석
피드백: 정렬 후 두 중첩 루프와 해시 집합으로 중복을 제거하는 방식이다. 최악의 경우 모든 쌍을 확인하므로 시간복잡도는 O(n^2)이고 추가 공간은 해시집합으로 O(n)이다.
개선 제안: 고려해볼 만한 대안: 기준값 고정 시 투포인터를 사용하면 해시세트 없이도 O(n^2) 시간과 O(1) 추가 공간으로 구현 가능하다.