diff --git a/contains-duplicate/kdh-92.java b/contains-duplicate/kdh-92.java new file mode 100644 index 000000000..942931bc8 --- /dev/null +++ b/contains-duplicate/kdh-92.java @@ -0,0 +1,35 @@ +class Solution { + public boolean containsDuplicate(int[] nums) { + /** + * Constraints + * - 1 <= nums[] <= 10^5 + * - -10^9 <= nums[i] <= 10^9 + * + * Output + * - true : 중복 값 존재 + * - false : 모든 값이 유일 + */ + + // 해결법 1 (HashMap 방식 - HashSet 유사) + // 시간복잡도: O(N), 공간 복잡도 : O(N) + Map countMap = new HashMap<>(); + + for (int num: nums) { + int count = countMap.getOrDefault(num, 0) + 1; + if (count > 1) return true; + countMap.put(num, count); + } + + return false; + + // 해결법 2 (정렬) + // 시간 복잡도 : O(N log N), 공간 복잡도 : O(1) + Arrays.sort(nums); + + for (int i = 0; i < nums.length - 1; i++) { + if (nums[i] == nums[i + 1]) return true; + } + + return false; + } +} diff --git a/house-robber/kdh-92.java b/house-robber/kdh-92.java new file mode 100644 index 000000000..a98ff6092 --- /dev/null +++ b/house-robber/kdh-92.java @@ -0,0 +1,29 @@ +class Solution { + public int rob(int[] nums) { + // (1) dp + // int n = nums.length; + + // if (n == 1) return nums[0]; + + // int[] dp = new int[n]; + + // dp[0] = nums[0]; + // dp[1] = Math.max(nums[0], nums[1]); + + // for (int i = 2; i < n; i++) { + // dp[i] = Math.max(dp[i - 1], nums[i] + dp[i - 2]); + // } + + // return dp[n - 1]; + + // (2) 인접 값 비교 + int prev = 0, curr = 0; + for (int num : nums) { + int temp = curr; + curr = Math.max(num + prev, curr); + prev = temp; + } + + return curr; + } +} diff --git a/longest-consecutive-sequence/kdh-92.java b/longest-consecutive-sequence/kdh-92.java new file mode 100644 index 000000000..f9fb62cbc --- /dev/null +++ b/longest-consecutive-sequence/kdh-92.java @@ -0,0 +1,61 @@ +/** + * Constraints: + * - 0 <= nums.length <= 105 + * - -109 <= nums[i] <= 109 + * + * Output + * - 가장 긴 길이 + * + * 풀이 특이점 + * - 둘다 시간복잡도는 O(N)으로 생각되는데 Runtime의 결과 차이가 꽤 크게 나온 점 + */ + +class Solution { + public int longestConsecutive(int[] nums) { + // (1) Set & num -1 + // 시간복잡도 : O(N) + // Runtime : 1267ms Beats 5.15% + // Memory : 63.30MB Beats 62.58% + // Set uniqueNums = Arrays.stream(nums).boxed().collect(Collectors.toSet()); + // int result = 0; + + // for (int num : nums) { + // if (uniqueNums.contains(num - 1)) continue; + // int length = 1; + // while (uniqueNums.contains(num + length)) length += 1; + // result = Math.max(length, result); + // } + + // return result; + + // (2) HashMap + // 시간복잡도 : O(N) + // Runtime : 38ms Beats 46.54% + // Memory : 66.45MB Beats 51.28% + HashMap hm = new HashMap<>(); + + for(int i=0; i frequencyMap = new HashMap<>(); + + for (int num : nums) { + frequencyMap.put(num, frequencyMap.getOrDefault(num, 0) + 1); + } + + PriorityQueue> minHeap = new PriorityQueue<>(Comparator.comparingInt(Map.Entry::getValue)); + + for (Map.Entry entry : frequencyMap.entrySet()) { + minHeap.offer(entry); + if (minHeap.size() > k) { + minHeap.poll(); + } + } + + int[] result = new int[k]; + + for (int i = 0; i < k; i++) { + result[i] = minHeap.poll().getKey(); + } + + return result; + + // (2) Stream + // 시간복잡도 : O(N log N) + // Runtime : 19ms Beats 8.16% + // Memory : 49.00MB Beats 20.01% + // Stream에 익숙해지기 위해 공부용 + return Arrays.stream(nums) + .boxed() + .collect(Collectors.groupingBy(num -> num, Collectors.summingInt(num -> 1))) + .entrySet().stream() + .sorted((a, b) -> b.getValue() - a.getValue()) + .limit(k) + .mapToInt(Map.Entry::getKey) + .toArray(); + + // (3) Array List + // 시간복잡도 : O(N) + // Runtime : 13ms Beats 75.77% + // Memory : 48.44MB Beats 61.68% + Map frequencyMap = new HashMap<>(); + for (int num : nums) { + frequencyMap.put(num, frequencyMap.getOrDefault(num, 0) + 1); + } + + List[] buckets = new List[nums.length + 1]; + for (int key : frequencyMap.keySet()) { + int freq = frequencyMap.get(key); + if (buckets[freq] == null) { + buckets[freq] = new ArrayList<>(); + } + buckets[freq].add(key); + } + + List result = new ArrayList<>(); + for (int i = buckets.length - 1; i >= 0 && result.size() < k; i--) { + if (buckets[i] != null) { + result.addAll(buckets[i]); + } + } + + return result.stream().mapToInt(Integer::intValue).toArray(); + } +} diff --git a/valid-palindrome/kdh-92.java b/valid-palindrome/kdh-92.java new file mode 100644 index 000000000..21fa3f61b --- /dev/null +++ b/valid-palindrome/kdh-92.java @@ -0,0 +1,65 @@ +/** + * Constraints + * - 1 <= s.length <= 2 * 10^5 + * - s consists only of printable ASCII characters. + * + * Output + * - true : 좌우 동일 + * - false : 좌우 비동일 + */ + + +class Solution { + public boolean isPalindrome(String s) { + + // 해결법 1 (투포인터) + // 시간복잡도: O(N), 공간 복잡도 : O(1) + // 2ms & Beats 99.05% + int left = 0, right = s.length() - 1; + + while (left < right) { + // (1) + if (!Character.isLetterOrDigit(s.charAt(left))) { + left++; + } + else if (!Character.isLetterOrDigit(s.charAt(right))) { + right--; + } + else { + if (Character.toLowerCase(s.charAt(left)) != Character.toLowerCase(s.charAt(right))) { + return false; + } + + left++; + right--; + } + + + // (2) + while (left < right && !Character.isLetterOrDigit(s.charAt(left))) { + left++; + } + while (left < right && !Character.isLetterOrDigit(s.charAt(right))) { + right--; + } + if (Character.toLowerCase(s.charAt(left)) != Character.toLowerCase(s.charAt(right))) { + return false; + } + left++; + right--; + } + + return true; + + // 해결법 2 (Stream API) + // 시간 복잡도 : O(N), 공간 복잡도 : O(N) + // 133ms & Beats 5.58% + String filtered = s.chars() + .filter(Character::isLetterOrDigit) + .mapToObj(c -> String.valueOf((char) Character.toLowerCase(c))) + .reduce("", String::concat); + + return IntStream.range(0, filtered.length() / 2) + .allMatch(i -> filtered.charAt(i) == filtered.charAt(filtered.length() - 1 - i)); + } +}