diff --git a/climbing-stairs/taekwon-dev.java b/climbing-stairs/taekwon-dev.java new file mode 100644 index 000000000..b3f7af935 --- /dev/null +++ b/climbing-stairs/taekwon-dev.java @@ -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]; + } +} diff --git a/combination-sum/taekwon-dev.java b/combination-sum/taekwon-dev.java new file mode 100644 index 000000000..94705db9b --- /dev/null +++ b/combination-sum/taekwon-dev.java @@ -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> answer = new ArrayList<>(); + private List combination = new ArrayList<>(); + + public List> 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); + } + } +} diff --git a/two-sum/taekwon-dev.java b/two-sum/taekwon-dev.java new file mode 100644 index 000000000..953f769cd --- /dev/null +++ b/two-sum/taekwon-dev.java @@ -0,0 +1,18 @@ +/** + * 시간/공간 복잡도: O(n) + */ +class Solution { + public int[] twoSum(int[] nums, int target) { + Map 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}; + } +}