diff --git a/contains-duplicate/GangBean.java b/contains-duplicate/GangBean.java new file mode 100644 index 000000000..a66343f82 --- /dev/null +++ b/contains-duplicate/GangBean.java @@ -0,0 +1,12 @@ +import java.util.Arrays; +import java.util.stream.Collectors; + +class Solution { + public boolean containsDuplicate(int[] nums) { + /*** + compare length of array and length of set. + O(n) given that n is length of array nums + */ + return nums.length > Arrays.stream(nums).boxed().collect(Collectors.toSet()).size(); + } +} diff --git a/house-robber/GangBean.java b/house-robber/GangBean.java new file mode 100644 index 000000000..c5138dd02 --- /dev/null +++ b/house-robber/GangBean.java @@ -0,0 +1,28 @@ +class Solution { + public int rob(int[] nums) { + /** + r[0] = a[0] + r[1] = max(a[1], r[0]) + r[2] = max(r[1], a[2] + r[0]) + r[3] = max(r[2], a[3] + r[1]) + ... + r[k] = max(r[k-1], a[k] + r[k-2]) O(1) + */ + int[] r = new int[nums.length]; + + for (int i = 0; i < nums.length; i++) { // O(N) + if (i == 0) { + r[i] = nums[i]; + continue; + } + if (i == 1) { + r[i] = Math.max(nums[i], r[i-1]); + continue; + } + r[i] = Math.max(r[i-1], nums[i] + r[i-2]); + } + + return r[nums.length - 1]; + } +} + diff --git a/longest-consecutive-sequence/GangBean.java b/longest-consecutive-sequence/GangBean.java new file mode 100644 index 000000000..c0b7beb86 --- /dev/null +++ b/longest-consecutive-sequence/GangBean.java @@ -0,0 +1,23 @@ +import java.util.*; +import java.util.stream.Collectors; + +class Solution { + public int longestConsecutive(int[] nums) { + Set set = Arrays.stream(nums).boxed().collect(Collectors.toSet()); + + int maxLength = 0; + for (int num: nums) { + // 각 숫자에 대해 최초 값이 가능하면, 즉 num-1이 존재하지 않으면 최대 length 구하기 + if (set.contains(num - 1)) continue; + int length = 1; + int start = num; + while (set.contains(start + 1)) { + length++; + start++; + } + maxLength = Math.max(length, maxLength); + } + + return maxLength; + } +} diff --git a/palindromic-substrings/GangBean.java b/palindromic-substrings/GangBean.java new file mode 100644 index 000000000..ebb22ac35 --- /dev/null +++ b/palindromic-substrings/GangBean.java @@ -0,0 +1,29 @@ +class Solution { + public int countSubstrings(String s) { + /** + 각 문자를 중간으로 갖는 palindrome 여부 체크 + + 두개의 문자를 중간으로 갖는 palindrome 여부 체크 + */ + int count = 0; + int length = s.length(); + for (int i = 0; i < length; i++) { // O(N) + int start = i; + int end = i; + while (0 <= start && end < length && start <= end && s.charAt(start) == s.charAt(end)) { // O(N) + count++; + start--; + end++; + } + + start = i; + end = i + 1; + while (0 <= start && end < length && start <= end && s.charAt(start) == s.charAt(end)) { // O(N) + count++; + start--; + end++; + } + } + + return count; // O(N^2) + } +} diff --git a/top-k-frequent-elements/GangBean.java b/top-k-frequent-elements/GangBean.java new file mode 100644 index 000000000..17a8cecac --- /dev/null +++ b/top-k-frequent-elements/GangBean.java @@ -0,0 +1,47 @@ +import java.util.*; +import java.util.stream.Collectors; + +class Solution { + public int[] topKFrequent(int[] nums, int k) { + /** + k번째로 많이 등장한 숫자를 구하는 문제. + 구해야 하는 것. + 1. 등장횟수의 순위 + 2. k번째 순위에 해당하는 수의 값 + + 1. 등장 횟수를 구하는 방법: 전체를 순회해 숫자별 등장 횟수를 저장 -> O(N) + 2. 등장 횟수의 순위를 구하는 방법: 등장 횟수에 대해 sort + -> O(MlogM) where N = M(M+1) / 2 + -> logN = logM + log(M+1) + C + -> M = N^(1/2) + -> O(MlogM) = O(N^1/2logN) (??? 여기가 맞는지 모르겠네요..) + 3. 역 인덱스를 구해 매핑되는 수를 구함 -> O(N) + + 전체: O(N) + */ + Map numToCount = new HashMap<>(); + for (int num : nums) { // O(N) + numToCount.put(num, numToCount.getOrDefault(num, 0) + 1); + } + + Map> countToNum = new HashMap<>(); + for (Map.Entry entry: numToCount.entrySet()) { + List numList = countToNum.getOrDefault(entry.getValue(), new ArrayList<>()); + numList.add(entry.getKey()); + countToNum.put(entry.getValue(), numList); + } // O(logN): because sum of all counts is equal to N + + List countRank = countToNum.keySet().stream().sorted(Collections.reverseOrder()).collect(Collectors.toList()); + // O(MlogM) where N = M(M+1) / 2 + + int[] ret = new int[k]; + int idx = 0; + int rank = 0; + while (idx < k) { // O(k) <= O(N) + for (int num : countToNum.get(countRank.get(rank++))) { + ret[idx++] = num; + } + } + return ret; + } +} diff --git a/valid-palindrome/GangBean.java b/valid-palindrome/GangBean.java new file mode 100644 index 000000000..121372857 --- /dev/null +++ b/valid-palindrome/GangBean.java @@ -0,0 +1,20 @@ +class Solution { + public boolean isPalindrome(String s) { + /** + * Step 1: Convert the input string to lowercase. -> O(n) + * Step 2: Remove all non-alphanumeric characters using regex. -> O(n) + * Step 3: Use two pointers to compare characters from both ends of the string. -> O(n) + * Total time complexity: O(n), where n is the length of the string. + */ + s = s.toLowerCase(); + s = s.replaceAll("[^a-z0-9]", ""); + int left = 0; + int right = s.length() - 1; + if (right <= 0) return true; + while (left < right) { + if (s.charAt(left++) != s.charAt(right--)) return false; + } + return true; + } +} +