diff --git a/3sum/hj4645.py b/3sum/hj4645.py new file mode 100644 index 000000000..712ad7407 --- /dev/null +++ b/3sum/hj4645.py @@ -0,0 +1,33 @@ +class Solution: + def threeSum(self, nums: List[int]) -> List[List[int]]: + nums.sort() # 배열 정렬해서 중복 처리와 투 포인터에 유리하게 만듦 + n = len(nums) + answer = [] + + for i in range(n - 2): + # i가 0이 아니면서 이전 값과 같으면 중복 방지를 위해 건너뜀 + if i > 0 and nums[i] == nums[i - 1]: + continue + + left, right = i + 1, n - 1 + + while left < right: + total = nums[i] + nums[left] + nums[right] + + if total == 0: + answer.append([nums[i], nums[left], nums[right]]) + + # left와 right가 가리키는 값이 중복이면 넘어감 + while left < right and nums[left] == nums[left + 1]: + left += 1 + while left < right and nums[right] == nums[right - 1]: + right -= 1 + + left += 1 + right -= 1 + elif total < 0: + left += 1 + else: + right -= 1 + + return answer diff --git a/climbing-stairs/hj4645.kt b/climbing-stairs/hj4645.kt new file mode 100644 index 000000000..8923db297 --- /dev/null +++ b/climbing-stairs/hj4645.kt @@ -0,0 +1,21 @@ +class Solution { + // 정상까지 n걸음이 소모된다고 할 때, n을 구할 수 있는 중복되지 않는 경우의 수를 계산하는 문제 + // 계단은 1걸음이나 2걸음씩 올라갈 수 있다. + fun climbStairs(n: Int): Int { + // 계단이 1개라면 무조건 1을 반환 + if(n == 1) return 1 + // 숫자로 된 배열을 선언(편의상 1번째 계단부터 시작하도록 n+1로 선언) + val dp = IntArray(n + 1) + // 첫번째 계단을 올라가는 방법은 1가지 + dp[1] = 1 + // 두번째 계단까지 올라가는 방법은 2가지(1+1, 2) + dp[2] = 2 + + //이제 3번째 계단부터 n번째 계단인 정상까지 올라가는 방법을 계산 + for(i in 3..n){ + dp[i] = dp[i - 1] + dp[i - 2] + } + return dp[n] + } +} + diff --git a/product-of-array-except-self/hj4645.py b/product-of-array-except-self/hj4645.py new file mode 100644 index 000000000..34dcbbb97 --- /dev/null +++ b/product-of-array-except-self/hj4645.py @@ -0,0 +1,22 @@ +class Solution: + # 정수 배열에 대해 answer 배열을 반환 + # 1. 정답 배열의 i번째 요소는 정수 배열의 i번째 요소를 제외한 다른 모든 요소의 곱 + # 2. 시간복잡도는 O(n) 이내로 해결 필요 + def productExceptSelf(self, nums: List[int]) -> List[int]: + length = len(nums) + answer = [1] * length # 1로 초기화 + + # 왼쪽 곱 계산 후 answer에 저장 + left = 1 + for i in range(length): + answer[i] = left + left *= nums[i] + + # 오른쪽 곱을 누적하면서 answer에 곱하기 + right = 1 + for i in range(length - 1, -1, -1): + answer[i] *= right + right *= nums[i] + + return answer + diff --git a/valid-anagram/hj4645.kt b/valid-anagram/hj4645.kt new file mode 100644 index 000000000..257eee0f1 --- /dev/null +++ b/valid-anagram/hj4645.kt @@ -0,0 +1,29 @@ +class Solution { + // t가 s의 철자를 모두 포함하고 있는 애너그램인지를 확인하는 문제 + // 푸는 방법은 2가지 + // 1. 유니코드로 변환해서 sort 해서 푸는 방법 + // 2. 정렬하지 않고 mutableMap으로 맵을 만들어 푸는 방법 + // 2번으로 문제를 풀었다. + fun isAnagram(s: String, t: String): Boolean { + //우선 처음부터 두 String의 길이가 다르면 바로 false를 반환 + if(s.length != t.length) false + + // s의 문자열을 카운트하면서 저장할 가변배열을 선언해준다. + val countMap = mutableMapOf() + + // s에 있는 각각의 문자들에 대해서 반복문을 돌면서 출현횟수를 맵으로 구성 + for(c in s){ + countMap[c] = countMap.getOrDefault(c, 0) + 1 + } + + // 이제 t의 문자들이 아까 만들어진 countMap에 모두 존재하는지 확인 + for(c in t){ + val count = countMap.getOrDefault(c, 0) + if (count == 0) return false + countMap[c] = count - 1 + } + // countMap에 들어있는 value가 전부 0이면 true를 반환 + return countMap.values.all { it == 0 } + } +} +