-
Notifications
You must be signed in to change notification settings - Fork 126
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[GangBean] Week 1 #630
[GangBean] Week 1 #630
Changes from all commits
e14cd76
dfaae6c
9381f46
c4f4785
2d6c164
b58d47d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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(); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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]; | ||
} | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
import java.util.*; | ||
import java.util.stream.Collectors; | ||
|
||
class Solution { | ||
public int longestConsecutive(int[] nums) { | ||
Set<Integer> 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; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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) | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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<Integer, Integer> numToCount = new HashMap<>(); | ||
for (int num : nums) { // O(N) | ||
numToCount.put(num, numToCount.getOrDefault(num, 0) + 1); | ||
} | ||
|
||
Map<Integer, List<Integer>> countToNum = new HashMap<>(); | ||
for (Map.Entry<Integer, Integer> entry: numToCount.entrySet()) { | ||
List<Integer> 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<Integer> countRank = countToNum.keySet().stream().sorted(Collections.reverseOrder()).collect(Collectors.toList()); | ||
// O(MlogM) where N = M(M+1) / 2 | ||
Comment on lines
+27
to
+35
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. PriorityQueue 대신 위 로직을 적용한 것으로 이해되는데 맞을까요?.? |
||
|
||
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; | ||
Comment on lines
+39
to
+45
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 저는 요 부분을 for문으로 했을 것 같은데 while문을 사용하셨네요! 👍 chatgpt에 물어보다보니 Bucket 방식 (Array + List) 이 있던데 빈도를 인덱스로 두고 해당하는 값들을 배열로 저장 처리하는 방식이 있더라구요. (장점 : 시간 복잡도를 O(N)으로 줄일 수 있습니다!) 추가적으로 while + for or for + for를 사용해 ret (result)를 추출하는 부분을 1개의 for문으로 해결할 수 있더라구요! 코드 간단하게 공유드립니당 :) // 빈도를 인덱스로 사용해 저장하는 방식
List<Integer>[] buckets = new List[nums.length + 1];
for (int key : numToCount.keySet()) {
int freq = numToCount.get(key);
if (buckets[freq] == null) {
buckets[freq] = new ArrayList<>();
}
buckets[freq].add(key);
}
// 1개의 for 문으로 결과물 처리
List<Integer> 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(); |
||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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]", ""); | ||
Comment on lines
+9
to
+10
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @kdh-92 안녕하세요! 스터디 기간 동안 잘 부탁드립니다:) 피드백주신 부분 관련 생각을 여쭤보고 싶습니다~
while (left < right) {
if (!Character.isLetterOrDigit(s.charAt(left))) left++;
if (!Character.isLetterOrDigit(s.charAt(right))) right--;
continue;
if(s.charAt(left) != s.charAt(right)) return false;
} 좋은 피드백 감사드립니다! 😄 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @GangBean 안녕하세요 :) 저도 잘 부탁드립니다!
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
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; | ||
} | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
contains-duplicate 쪽에서도 Stream을 사용하셨었는데 Stream에 익숙하신가요?
(저는 아직 문제보고 바로 적용하는게 어렵더라구요 ㅠㅠ)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
stream 의도적으로 써보려고 연습중입니다 ㅎㅎ 새로 맡은 업무 코드가 대부분 stream 으로 작성되어 있어서요~
이번 스터디 기간동안 익숙해지는 걸 목표로 같이 해봐요!