diff --git a/contains-duplicate/Geegong.java b/contains-duplicate/Geegong.java index 348e341ae..e010bdadf 100644 --- a/contains-duplicate/Geegong.java +++ b/contains-duplicate/Geegong.java @@ -9,17 +9,26 @@ public class Geegong { * time complexity : O(n) * space complexity : o(n) * @param nums - * @return + * @return boolean */ public boolean containsDuplicate(int[] nums) { + + + HashSet uniques = new HashSet<>(); for (int num : nums) { - if (uniques.contains(num)) { + + // 명확하게 hashSet에 값이 있는지 체크하는 메소드로 확인이 가능하지만 +// if (uniques.contains(num)) { +// return true; +// } +// uniques.add(num); + + // hashSet 의 Add 는 이미 값이 있다면 FALSE를 리턴하기에 아래처럼도 동작 가능 (더 빠른 결과확인) + if (!uniques.add(num)) { return true; } - - uniques.add(num); } return false; diff --git a/house-robber/Geegong.java b/house-robber/Geegong.java index 0fa2a7832..8f2f71eb6 100644 --- a/house-robber/Geegong.java +++ b/house-robber/Geegong.java @@ -1,4 +1,52 @@ +import java.util.HashMap; +import java.util.Map; + public class Geegong { - // 이 문제는 시간이 남을때 풀 예정 😅 + + /** + * top-down + memoization 방식으로 풀이 + * memoization (memo 변수) 없이 풀이하면 Time Limit Exceeded 발생 + * time complexity : O(N) -> memo 가 있어서 이미 연산이 된건 패스함 + * space complexity : O(N) -> index 만큼의 연산 결과가 있음 + * @param nums + * @return + */ + public int rob(int[] nums) { + // memoization 하지 않으면 Time Limit Exceeded. + Map memo = new HashMap<>(); + + int maxAmount = 0; + for (int idx=0; idx memo) { + if (currIdx == origin.length - 1) { + return origin[currIdx]; + } else if (currIdx >= origin.length) { // when out of bounds + return 0; + } + + if (memo.containsKey(currIdx)) { + return memo.get(currIdx); + } + + int currentVal = origin[currIdx]; + + int maxAmount = Math.max( + currentVal + rob(origin, currIdx + 2, memo), rob(origin, currIdx+1, memo)); + + memo.put(currIdx, maxAmount); + + return maxAmount; + } + + } diff --git a/longest-consecutive-sequence/Geegong.java b/longest-consecutive-sequence/Geegong.java index 2a0e5624e..61fa2d51a 100644 --- a/longest-consecutive-sequence/Geegong.java +++ b/longest-consecutive-sequence/Geegong.java @@ -1,3 +1,4 @@ +import java.util.Arrays; import java.util.HashMap; import java.util.HashSet; import java.util.Map; @@ -7,42 +8,45 @@ */ public class Geegong { + /** + * Time complexity : O(N) + O(N long N) + O(N) + * - o(N) : 한번 순회해서 set + * - O(N log N) : sorting + * - O (N) : sorting된걸 한번 더 순회 + * Space complexity : O(N) -> hash set + * @param nums + * @return int + */ public int longestConsecutive(int[] nums) { - HashSet setOfNums = new HashSet<>(); - // key : startIndex , value : length - Map lengthMap = new HashMap<>(); - - // sort..? 를 해야될까 싶음.. - - // initialize - for (int num : nums) { - setOfNums.add(num); + if (nums.length == 0) { + return 0; } - Integer longest = 0; - - for (Integer num : setOfNums) { - int length = iterate(setOfNums, num, 0, lengthMap); - longest = Math.max(longest, length); + // hashSet + HashSet hashSet = new HashSet<>(); + for (int num : nums) { + hashSet.add(num); } - return longest; - } + int[] sortedNums = hashSet.stream().mapToInt(val -> val).sorted().toArray(); - public Integer iterate(HashSet hashSet, int currIndex, int currLength, Map lengthMap) { - if (lengthMap.containsKey(currIndex)) { - return lengthMap.get(currIndex); - } + int maxLength = 1; + int currentLength = 1; + int prev = sortedNums[0]; + for(int index=1; index numMap = new HashMap<>(); - // key : frequency of num elements / value : HashSet num elements - Map> frequencyMap = new HashMap<>(); + /** + * Map 으로 빈도수를 key , 빈도수에 해당되는 num 들을 list 로 저장 + * key (빈도수) 를 sorting + * k 만큼 골라낸다 + * Time Complexity : O(N) + O(N logN) + O(N) + * - O(N) : nums 만큼 iterate + * - O(N log N) : sorting + * - O(N) : frequency 그룹핑된 그룹 갯수만큼 iterate + * @param nums + * @param k + * @return int[] + */ + public int[] topKFrequent(int[] nums, int k) { - // most frequent numbers - int maxCount = 0; + // key : frequency , value : list of nums + Map> map = new HashMap<>(); + Arrays.sort(nums); + int current = nums[0]; + int count = 1; - // initialize numMap - for (int num : nums) { - if (numMap.containsKey(num)) { - Integer alreadyCounted = numMap.get(num); - numMap.put(num, alreadyCounted + 1); + for (int i = 1; i < nums.length; i++) { + if (nums[i] == current) { + count++; } else { - numMap.put(num, 1); + map.computeIfAbsent(count, el -> new ArrayList<>()).add(current); + current = nums[i]; + count = 1; } } + // Add last group + map.computeIfAbsent(count, el -> new ArrayList<>()).add(current); - //numHashSetMap - for (int num : numMap.keySet()) { - int frequencyOfNum = numMap.get(num); - maxCount = Math.max(maxCount, frequencyOfNum); - - if (frequencyMap.containsKey(frequencyOfNum)) { - HashSet alreadySet = frequencyMap.get(frequencyOfNum); - alreadySet.add(num); - - frequencyMap.put(frequencyOfNum, alreadySet); - - } else { - HashSet newHashSet = new HashSet<>(); - newHashSet.add(num); - - frequencyMap.put(frequencyOfNum, newHashSet); - } - } + List sortedFrequency = map.keySet().stream().sorted(Comparator.reverseOrder()).toList(); + List result = new ArrayList<>(); + for (int index=0; index numsOfFreq = map.get(mostFrequency); + for(int innerIndex = 0; innerIndex=0; frequency--) { - if (resultIndex >= result.length) { - return result; + result.add(numsOfFreq.get(innerIndex)); } - if (frequencyMap.containsKey(frequency)) { - HashSet numElements = frequencyMap.get(frequency); - - for (int numElement : numElements) { - result[resultIndex] = numElement; - resultIndex++; - - - if (resultIndex >= result.length) { - return result; - } - } - } } - return result; + return result.stream().mapToInt(Integer::intValue).toArray(); + +// 아래 문제풀이는 예전 기수에 풀었던 방법으로 Map 으로 빈도수와 num을 관리하는 값을 가지긴 하나 +// sorting은 하지 않고 maxNumOfFrequency를 구하여 순차적으로 작은 값들을 꺼내서 k만큼 리턴한다 +// int[] result = new int[k]; +// +// // key : num element in nums / value : frequency of num elements +// Map numMap = new HashMap<>(); +// +// // key : frequency of num elements / value : HashSet num elements +// Map> frequencyMap = new HashMap<>(); +// +// // most frequent numbers +// int maxCount = 0; +// +// // initialize numMap +// for (int num : nums) { +// if (numMap.containsKey(num)) { +// Integer alreadyCounted = numMap.get(num); +// numMap.put(num, alreadyCounted + 1); +// } else { +// numMap.put(num, 1); +// } +// } +// +// +// //numHashSetMap +// for (int num : numMap.keySet()) { +// int frequencyOfNum = numMap.get(num); +// maxCount = Math.max(maxCount, frequencyOfNum); +// +// if (frequencyMap.containsKey(frequencyOfNum)) { +// HashSet alreadySet = frequencyMap.get(frequencyOfNum); +// alreadySet.add(num); +// +// frequencyMap.put(frequencyOfNum, alreadySet); +// +// } else { +// HashSet newHashSet = new HashSet<>(); +// newHashSet.add(num); +// +// frequencyMap.put(frequencyOfNum, newHashSet); +// } +// } +// +// +// // maxCount 부터 decreasing +// int resultIndex=0; +// for(int frequency=maxCount; frequency>=0; frequency--) { +// if (resultIndex >= result.length) { +// return result; +// } +// +// if (frequencyMap.containsKey(frequency)) { +// HashSet numElements = frequencyMap.get(frequency); +// +// for (int numElement : numElements) { +// result[resultIndex] = numElement; +// resultIndex++; +// +// +// if (resultIndex >= result.length) { +// return result; +// } +// } +// } +// } +// +// return result; + } } diff --git a/two-sum/Geegong.java b/two-sum/Geegong.java index 3fd371057..3dd411549 100644 --- a/two-sum/Geegong.java +++ b/two-sum/Geegong.java @@ -8,26 +8,22 @@ public class Geegong { * space complexity : O(n) * @param nums * @param target - * @return + * @return int[] */ public int[] twoSum(int[] nums, int target) { - Map map = new HashMap<>(); int[] result = new int[2]; + // key : value, value = index + Map maps = new HashMap(); - // if target = -9 / num = 1 , num = -10 - for (int index=0; index