-
-
Notifications
You must be signed in to change notification settings - Fork 245
[윤태권] Week3 문제 풀이 #395
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
[윤태권] Week3 문제 풀이 #395
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,28 @@ | ||
/** | ||
* 시간 복잡도: O(n) | ||
* - n = 5 경우를 가정하고 생각해보기 | ||
* - 3층 계단 -> 2층, 1층 계산 (이 경우는 이미 메모되어 있어서 별도로 계산하진 않음) | ||
* - 4층 계단 -> 3층, 2층 계산 (2층은 메모에 있는 것 활용) | ||
* - 5층 계단 -> 4층, 3층 계산 (3층은 메모에 있는 것 활용) | ||
* - ... | ||
* - 각 단계 별로 (메모를 활용해) 아직 계산되지 않은 것을 한 번씩 호출하게 되므로 O(n) | ||
* - 근데 만약 메모를 사용하지 않으면? (중복 호출이 많이 일어남 ... O(n^2)) | ||
* | ||
* 공간 복잡도: O(n) | ||
*/ | ||
class Solution { | ||
public int climbStairs(int n) { | ||
int[] memo = new int[n + 1]; | ||
return climbStairs(n, memo); | ||
} | ||
|
||
public int climbStairs(int n, int[] memo) { | ||
if (n == 1) return 1; | ||
if (n == 2) return 2; | ||
|
||
if (memo[n] > 0) return memo[n]; | ||
|
||
memo[n] = climbStairs(n - 1, memo) + climbStairs(n - 2, memo); | ||
return memo[n]; | ||
} | ||
} |
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,46 @@ | ||
/** | ||
* 알고리즘: 백트랙킹 | ||
* 시간 복잡도: O(n^t) | ||
* - n: candidates.lenth | ||
* - t: target / candidates의 최솟값 | ||
* - 예시를 통해 시간 복잡도를 이해해보자! | ||
* | ||
* - candidates: [2, 3], target: 6 | ||
* - [2] -> [2, 2] -> [2, 2, 2] -> OK (여기서 생각해보면, 아 재귀를 최대 6/2 만큼 타고 들어가겠군?) | ||
* - [2, 2] -> [2, 2, 3] -> X | ||
* - [2] -> [2, 3] -> [2, 3, 3] -> X | ||
* - [3] -> [3, 3] -> OK | ||
* - 중간에 sum > target, sum == target 인 경우 return 하기 때문에 모든 케이스를 다 검사하진 않지만 | ||
* - 기본적으로 아래와 같이 문제를 풀게 될 경우 최악의 경우에는 O(n^t) 만큼 소요된다. | ||
* | ||
* 공간 복잡도: O(t) | ||
* - t: target / candidates의 최솟값 | ||
* - 이것도 생각해보니까 주어진 candidates.length (=n) 값에 비례하는 게 아니라 | ||
* - (가능한 케이스에서) 가장 작은 값으로 타겟을 채우는 게 가장 많은 사이즈를 차지하는 값이 될텐데, 이것에 영향을 받겠군. | ||
* | ||
*/ | ||
class Solution { | ||
|
||
private List<List<Integer>> answer = new ArrayList<>(); | ||
private List<Integer> combination = new ArrayList<>(); | ||
|
||
public List<List<Integer>> combinationSum(int[] candidates, int target) { | ||
backtracking(candidates, target, 0, 0); | ||
return answer; | ||
} | ||
|
||
private void backtracking(int[] candidates, int target, int sum, int start) { | ||
if (sum > target) { | ||
return; | ||
} | ||
if (sum == target) { | ||
answer.add(new ArrayList<>(combination)); | ||
return; | ||
} | ||
for (int i = start; i < candidates.length; i++) { | ||
combination.add(candidates[i]); | ||
backtracking(candidates, target, sum + candidates[i], i); | ||
combination.remove(combination.size() - 1); | ||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
/** | ||
* 시간/공간 복잡도: O(n) | ||
*/ | ||
class Solution { | ||
public int[] twoSum(int[] nums, int target) { | ||
Map<Integer, Integer> map = new HashMap<>(); | ||
|
||
for (int idx = 0; idx < nums.length; idx++) { | ||
int complement = target - nums[idx]; | ||
if (map.containsKey(complement)) { | ||
return new int[]{map.get(complement), idx}; | ||
} | ||
map.put(nums[idx], idx); | ||
} | ||
|
||
return new int[]{-1, -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. 저는 js를 사용하여 이와 비슷한 방식으로 풀이를 했는데요, 마지막에 return new int[]{-1, -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. @seona926 안녕하세요! 질문 감사합니다. 우선 결론부터 말씀드리면 해당 코드는 풀이와 관련한 의미를 가지진 않습니다! Java 문법상 어쩔 수 없이 추가한 부분이라고 보시면 좋은데요. 우선 문제 조건에 public int[] twoSum(int[] nums, int target) {
Map<Integer, Integer> map = new HashMap<>();
for (int idx = 0; idx < nums.length; idx++) {
int complement = target - nums[idx];
if (map.containsKey(complement)) {
// 문제 제한 조건 상 중간에 반드시 이 리턴문이 실행돼서, 마지막 리턴문 실행 안됨.
return new int[]{map.get(complement), idx};
}
map.put(nums[idx], idx);
}
// 이 부분은 실행되지 않지만, 문법적으로 반드시 이 메서드는 int[] 를 리턴해야 함
return new int[]{-1, -1};
} 사실 위 코드에서 중간에 early return 이 반드시 되기 때문에 마지막 줄에 있는 return 문이 실행되지는 않습니다. 그런데 만약에 early return 부분만 있다면, 문법상 해당 메서드가 특정 조건에는 |
||
} | ||
} |
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.
풀이를 따라갈 수 있어 이해하기 좋았습니다! 고생하셨습니다!