diff --git a/contains-duplicate/jinvicky.java b/contains-duplicate/jinvicky.java new file mode 100644 index 000000000..de8319e22 --- /dev/null +++ b/contains-duplicate/jinvicky.java @@ -0,0 +1,11 @@ +import java.util.*; + +class Solution { + public boolean containsDuplicate(int[] nums) { + Set set = new HashSet<>(); + for (int num : nums) { + if (!set.add(num)) return true; + } + return false; + } +} diff --git a/house-robber/jinvicky.java b/house-robber/jinvicky.java new file mode 100644 index 000000000..b6b6354a7 --- /dev/null +++ b/house-robber/jinvicky.java @@ -0,0 +1,19 @@ +//dp[0] -> 1번째 집 털이 수완으로 초기화 +//dp[1] -> -2집 털이+지금집 털이가 -1집 털이보다 수완이 좋다. = -2집 털이(0)+지금집 털이 = 7 +//dp[2] -> -2집 털이+지금집 털이가 -1집 털이보다 수완이 좋다. = -2집 털이+지금집 털이 = 11 +//dp[3] -> -2집 털이+지금집 털이가 -1집 털이보다 수완이 좋다. = -2집 털이+지금집 털이 = 11 (>10) +//dp[4] -> -2집 털이+지금집 털이가 -1집 털이보다 수완이 좋다. = -2집 털이+지금집 털이 = 12 (>10) +class Solution { + public int rob(int[] nums) { + int[] dp = new int[nums.length]; + dp[0] = nums[0]; + + for (int i = 1; i < nums.length; i++) { + int prev2AndNowRob = (i - 2 < 0 ? 0 : dp[i - 2]) + nums[i]; + int prev1Rob = dp[i - 1]; + + dp[i] = Math.max(prev2AndNowRob, prev1Rob); + } + return dp[nums.length - 1]; + } +} diff --git a/longest-consecutive-sequence/jinvicky.java b/longest-consecutive-sequence/jinvicky.java new file mode 100644 index 000000000..01e9cf62a --- /dev/null +++ b/longest-consecutive-sequence/jinvicky.java @@ -0,0 +1,32 @@ +import java.util.HashSet; +import java.util.Set; + +// 연속적인 숫자의 길이를 구하는 것이기 때문에 이전, 다음 수가 집합의 일부인지를 파악해야 한다. +// map, set 자료구조를 사용하면 조회 성능을 O(1)로 높일 수 있다. +// 어려웠던 점은 연속적인 숫자의 start가 되냐 여부 조건을 떠올리는 것이었다. while문이 약해서 length++하는 로직이 힘들었다. +// 문제의 조건은 배열 내에서의 연속적인 숫자의 길이이기 때문에 while을 사용해도 성능 이슈 걱정할 필요가 없었다. +class Solution { + public int longestConsecutive(int[] nums) { + Set set = new HashSet<>(); + + for (int n : nums) { + set.add(n); + } + + int maxLength = 0; + + for (int n : nums) { + if (!set.contains(n - 1)) { // 내 이전 숫자가 집합에 없다 == 내가 최소 숫자다. + int length = 1; + + while (set.contains(n + length)) { + length++; + } + + maxLength = Math.max(length, maxLength); + } + } + + return maxLength; + } +} diff --git a/top-k-frequent-elements/jinvicky.java b/top-k-frequent-elements/jinvicky.java new file mode 100644 index 000000000..005411266 --- /dev/null +++ b/top-k-frequent-elements/jinvicky.java @@ -0,0 +1,42 @@ +import java.util.HashMap; +import java.util.Map; +import java.util.PriorityQueue; + +class Solution { + public int[] topKFrequent(int[] nums, int k) { + // [풀이] + // 1. <숫자: 빈도수>를 저장하는 HashMap과 [빈도수, 숫자]를 저장하는 PriorityQueue를 선언한다. + // 2. HashMap에 숫자별로 빈도수를 함께 저장해서 해시테이블을 만든다. + // [우선순위 큐에 사용된 자료구조] + // 1. 별도 클래스를 선언 + // 2. 요구사항 자료형 배열을 선언한다. + // 처음에는 별도 클래스를 선언했다가 값이 2개이며 알고리즘 로직 자체가 어려워서 int[] 구조로 풀이했다. + // (주로 알고리즘이 어려우면 가독성이 나쁘더라도 자료구조를 단순화하는 습관이 있다) + // [어려웠던 점] + // 1. 우선순위 큐는 매번 요소가 추가될 때마다 내부 정렬을 수행하기 때문에 연산을 수행하면서 k개를 유지해야 한다. + // 또한 기존 [빈도수, 숫자]를 버려야만 올바른 답을 도출할 수 있었다. + // 2. [숫자, 빈도수]로 저장하는 것만 생각했더니 내부 정렬을 어떻게 하지 못해서 굉장히 고민했다. 정답은 반대였다. + + int[] answer = new int[k]; + + Map map = new HashMap<>(); + for (int n : nums) { + map.put(n, map.getOrDefault(n, 0) + 1); + } + PriorityQueue pq = new PriorityQueue<>((a, b) -> a[0] - b[0]); + + for (int key : map.keySet()) { + pq.add(new int[]{map.get(key), key}); + if (pq.size() > k) { + pq.poll(); + } + } + + for (int i = 0; i < k; i++) { + if (!pq.isEmpty()) { + answer[i] = pq.poll()[1]; + } + } + return answer; + } +} diff --git a/two-sum/jinvicky.java b/two-sum/jinvicky.java new file mode 100644 index 000000000..aed3a75a5 --- /dev/null +++ b/two-sum/jinvicky.java @@ -0,0 +1,36 @@ +import java.util.HashMap; +import java.util.Map; + +/** + * 본래 brute force로 이중 for문으로 풀었다가 map으로 최적화. + */ +class Solution { + + public int[] twoSumByBruteForce(int[] nums, int target) { + for (int i = 0; i < nums.length; i++) { + for (int j = i + 1; j < nums.length; j++) { + if (nums[i] + nums[j] == target) { + return new int[]{i, j}; + } + } + } + return new int[2]; + } + + public int[] twoSum(int[] nums, int target) { + Map numberMap = new HashMap<>(); + + for (int i = 0; i < nums.length; i++) { + int required = target - nums[i]; + Integer index = numberMap.get(required); + + if (index != null) { + return new int[]{index, i}; + } + + numberMap.put(nums[i], i); + } + + return new int[2]; + } +}