diff --git a/climbing-stairs/suhyenim.java b/climbing-stairs/suhyenim.java new file mode 100644 index 000000000..c3153a098 --- /dev/null +++ b/climbing-stairs/suhyenim.java @@ -0,0 +1,82 @@ +/* [5th/week02] 70. Climbing Stairs + +1. 문제 요약 +링크: https://leetcode.com/problems/climbing-stairs/description/ +한 번에 1칸이나 2칸을 올라갈 수 있을 때, n칸을 올라가는 방법의 수는? + +2. 문제 풀이 +풀이1: 1, 2칸을 올라가는 방법의 수는 이미 알기 때문에, "n칸을 올라가는 방법의 수 = n-2칸을 올라가는 방법의 수 + n-1칸을 올라가는 방법의 수"를 반복 +성공: Time: 0 ms (100%), Space: 40.4 MB (50.46%) +=> 시간 복잡도: O(n), 공간 복잡도: O(n) + +class Solution { + public int climbStairs(int n) { + Map dp = new HashMap<>(); + dp.put(1, 1); + dp.put(2, 2); + for (int i = 3; i <= n; i++){ + dp.put(i, dp.get(i - 2) + dp.get(i - 1)); + } + return dp.get(n); + } +} + +풀이2: 풀이1과 논리는 같지만, HashMap을 사용하지 않음으로써 공간 복잡도를 낮춤 +성공: Time: 0 ms (100%), Space: 40.1 MB (97.08%) +=> 시간 복잡도: O(n), 공간 복잡도: O(1) + +class Solution { + public int climbStairs(int n) { + if (n < 3){ + return n; + } + int n1 = 1, n2 = 2; + for (int i = 0; i < n - 2; i++){ + int n3 = n1 + n2; + n1 = n2; + n2 = n3; + } + return n2; + } +} + +풀이3: 풀이1은 반복문(bottom-up) DP이고, 풀이3은 재귀+메모이제이션(top-down) DP임 +성공: Time: 0 ms (100%), Space: 40.5 MB (50.46%) +=> 시간 복잡도: O(n), 공간 복잡도: O(n) + +class Solution { + private Map memo = new HashMap<>(); + + public int climbStairs(int n) { + if (memo.containsKey(n)) { + return memo.get(n); + } + + if (n < 3) { + return n; + } + + int result = climbStairs(n - 1) + climbStairs(n - 2); + memo.put(n, result); + return result; + } +} + +3. TIL +재귀에다가 메모이제이션을 더하면 +=> 큰 문제는 재귀적으로 쪼개서 풀되, 이미 계산한 작은 문제의 결과는 메모(map)에 저장해두었다가 꺼내 쓸 수 있기 때문에 +=> 중복 계산을 방지함으로써 시간 복잡도를 아낄 수 있다. + +*/ + +class Solution { + public int climbStairs(int n) { + Map dp = new HashMap<>(); + dp.put(1, 1); + dp.put(2, 2); + for (int i = 3; i <= n; i++){ + dp.put(i, dp.get(i - 2) + dp.get(i - 1)); + } + return dp.get(n); + } +} diff --git a/product-of-array-except-self/suhyenim.java b/product-of-array-except-self/suhyenim.java new file mode 100644 index 000000000..1ab6466d9 --- /dev/null +++ b/product-of-array-except-self/suhyenim.java @@ -0,0 +1,93 @@ +/* [5th/week02] 238. Product of Array Except Self + +1. 문제 요약 +링크: https://leetcode.com/problems/product-of-array-except-self/description/ +각 인덱스 i에 대해, num[i]를 제외한 모든 값들을 곱해서 배열로 반환 +(주의: 나누기 안됨, 시간 복잡도 O(n) 내로 동작해야 함) + +2. 문제 풀이 +풀이1: 인덱스 i를 기점으로, 이전 값들의 누적곱 배열 & 이후 값들의 누적곱 배열을 만들고 -> 각 인덱스 i에 대해, 두 배열 값 곱하기 +성공: Time: 2 ms (87.36%), Space: 56.5 MB (10.9%) +=> 시간 복잡도: O(n), 공간 복잡도: O(n) + +class Solution { + public int[] productExceptSelf(int[] nums) { + int n = nums.length; + int[] before = new int[n]; + int[] after = new int[n]; + int[] products = new int[n]; + + before[0] = 1; + for (int i = 0; i < n - 1; i++) { + before[i + 1] = before[i] * nums[i]; + } + + after[n - 1] = 1; + for (int i = n - 1; i > 0; i--) { + after[i - 1] = after[i] * nums[i]; + } + + for (int i = 0; i < n; i++) { + products[i] = before[i] * after[i]; + } + + return products; + } +} + +풀이2: 풀이1과 논리는 동일하지만, 누적곱을 배열을 사용해서 저장해두는 것이 아니라 변수 하나를 사용해서 저장하도록 변경 +성공: Time: 3 ms (19.55%), Space: 55.4 MB (61.74%) +=> 시간 복잡도: 시간 복잡도: O(n), 공간 복잡도: 결과 배열 제외하면 O(1) + +class Solution { + public int[] productExceptSelf(int[] nums) { + int n = nums.length; + int[] products = new int[n]; + Arrays.fill(products, 1); + + int leftProduct = 1; + for (int i = 0; i < n - 1; i++) { + leftProduct *= nums[i]; + products[i + 1] *= leftProduct; + } + + int rightProduct = 1; + for (int i = n - 1; i > 0; i--) { + rightProduct *= nums[i]; + products[i - 1] *= rightProduct; + } + + return products; + } +} + +3. TIL +동적 계획법(DP)이란? +큰 문제를 작은 부분 문제로 나누고, 그 부분 문제들의 해를 저장해 두었다가(메모이제이션/테이블), 필요할 때 재사용해서 전체 문제를 효율적으로 해결하는 기법이다. + +*/ + +class Solution { + public int[] productExceptSelf(int[] nums) { + int n = nums.length; + int[] before = new int[n]; + int[] after = new int[n]; + int[] products = new int[n]; + + before[0] = 1; + for (int i = 0; i < n - 1; i++) { + before[i + 1] = before[i] * nums[i]; + } + + after[n - 1] = 1; + for (int i = n - 1; i > 0; i--) { + after[i - 1] = after[i] * nums[i]; + } + + for (int i = 0; i < n; i++) { + products[i] = before[i] * after[i]; + } + + return products; + } +} diff --git a/valid-anagram/suhyenim.java b/valid-anagram/suhyenim.java new file mode 100644 index 000000000..0aa681ce4 --- /dev/null +++ b/valid-anagram/suhyenim.java @@ -0,0 +1,81 @@ +/* [5th/week02] 242. Valid Anagram + +1. 문제 요약 +링크: https://leetcode.com/problems/valid-anagram/description/ +문자열 t가 문자열 s의 anagram이면 true 반환 + +2. 문제 풀이 +제출1: 길이가 다른지 우선 체크하고 -> 각 문자열을 배열로 만들어서 오름차순 정렬 후, 반복문을 돌면서 문자가 다르면 false 반환 +성공: Time: 3 ms (91.78%), Space: 44.6 MB (43.28%) +=> 시간 복잡도: O(nlogn), 공간 복잡도: O(n) + +class Solution { + public boolean isAnagram(String s, String t) { + if (s.length() != t.length()){ + return false; + } + char[] ss = s.toCharArray(); + char[] tt = t.toCharArray(); + Arrays.sort(ss); + Arrays.sort(tt); + for (int i = 0; i < s.length(); i++){ + if (ss[i] != tt[i]){ + return false; + } + } + return true; + } +} + +풀이2: 길이가 다른지 우선 체크하고 -> s를 {문자:횟수} 구조의 HashMap으로 만든 후 -> t의 문자들과 비교해서 같으면 {키:밸류}쌍 삭제 -> 최종적으로 {키:밸류}쌍이 0개면 true 반환 +성공: Time: 15 ms (25.19%), Space: 45 MB (10.95%) +=> 시간 복잡도: O(n), 공간 복잡도: O(n) + +class Solution { + public boolean isAnagram(String s, String t) { + if (s.length() != t.length()) { + return false; + } + + Map count = new HashMap<>(); + for (char c : s.toCharArray()) { + count.put(c, count.getOrDefault(c, 0) + 1); + } + + for (char c : t.toCharArray()) { + if (!count.containsKey(c)) { + return false; + } + count.put(c, count.get(c) - 1); + if (count.get(c) == 0) { + count.remove(c); + } + } + + return count.isEmpty(); + } +} + +3. TIL +Map에는 다양한 메소드가 있다. ex) getOrDefault(), containsKey(), put(), get(), remove() 등 +getOrDefault() 내부 구현에는 containsKey()가 사용된다. + +*/ + +class Solution { + public boolean isAnagram(String s, String t) { + if (s.length() != t.length()){ + return false; + } + char[] ss = s.toCharArray(); + char[] tt = t.toCharArray(); + Arrays.sort(ss); + Arrays.sort(tt); + for (int i = 0; i < s.length(); i++){ + if (ss[i] != tt[i]){ + return false; + } + } + return true; + } +}