Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 23 additions & 33 deletions longest-consecutive-sequence/jaejeong1.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,43 +4,33 @@
class SolutionLongestConsecutiveSequence {

public int longestConsecutive(int[] nums) {
// 정렬되지 않은 정수 nums 배열이 주어지면 가장 긴 연속 요소 시퀀스 길이를 반환
// O(N) 시간 내 실행되야함
// 전부 해시맵에 때려넣고, 키를 꺼내 연속 요소가 있는지 확인한다
// 연속 요소가 있으면 answer를 1 증가시키고, 연속 요소는 제거한다
// 시간복잡도: O(N), 공간복잡도: O(N)

Set<Integer> set = new HashSet<>();
for (var num : nums) {
set.add(num);
}
var answer = 0;
for (var num : nums) {
var length = 1;

if (set.contains(num-1)) {
set.remove(num);
var minusKey = num;
while (set.contains(--minusKey)) {
length++;
set.remove(minusKey);
}
// 시퀀스 조회를 O(1)에 수행 가능하고, 중복은 무시할 수 있는 조건이므로 Set이 적합한 자료구조
// 시간복잡도: O(N), 공간복잡도: O(N)
Set<Integer> num_set = new HashSet<Integer>();
for (int num : nums) {
num_set.add(num);
}

if (set.contains(num+1)) {
set.remove(num);
var plusKey = num;
while (set.contains(++plusKey)) {
length++;
set.remove(plusKey);
}
}
int longestSequence = 0;

// 시간복잡도: O(N)
for (int num : num_set) {
// 시퀀스 중간에 있는 숫자가 아닌 시작하는 숫자를 찾음
// 시작하는 숫자는 - 1 값이 Set에 없을 것
if (!num_set.contains(num - 1)) {
int currentNum = num;
int currentLength = 1;
// + 1 값이 Set에 있는 지 확인하면서 증가
while (num_set.contains(currentNum + 1)) {
currentNum += 1;
currentLength += 1;
}

if (length > answer) {
answer = length;
// 순회가 끝나면 최대 시퀀스 길이인지 확인하고 적용
longestSequence = Math.max(longestSequence, currentLength);
}
}
}

return answer;
return longestSequence;
}
}
41 changes: 26 additions & 15 deletions top-k-frequent-elements/jaejeong1.java
Original file line number Diff line number Diff line change
@@ -1,24 +1,35 @@
import java.util.HashMap;
import java.util.Map;
import java.util.PriorityQueue;
import java.util.Queue;

class SolutionTopKFrequentElements {
public int[] topKFrequent(int[] nums, int k) {
// 빈도순으로 k개 반환
// 빈도 체크: 해시맵으로 카운트. 시간복잡도 O(N), 공간복잡도 O(N)
// 빈도순 정렬: sorting, 시간복잡도 O(N log N), 공간복잡도 O(N)
// 합산: 시간복잡도 O(N log N), 공간복잡도 O(N)
// 풀이
// 시간복잡도: O(N log K), 공간복잡도: O(N)

// 빈도 체크
Map<Integer, Integer> freq = new HashMap<>();
for (int num : nums) {
freq.put(num, freq.getOrDefault(num, 0) + 1);
}
// 숫자 별 빈도 누적을 Map 이용
// 시간복잡도: O(N), 공간복잡도: O(N)
Map<Integer, Integer> count = new HashMap<>();
for (int n: nums) {
count.put(n, count.getOrDefault(n, 0) + 1);
}

// 빈도순 정렬
return freq.keySet().stream()
.sorted((a, b) -> freq.get(b) - freq.get(a))
.mapToInt(i -> i)
.limit(k) // 배열에서 상위 k개만 반환
.toArray();
Queue<Integer> heap = new PriorityQueue<>((x, y) -> count.get(x) - count.get(y));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

안녕하세요.
우선순위큐를 써야지 O(n log(K))가 가능하군요.
작성을 잘해주셔서 새로 배웠네요!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

네, 저도 다시 풀어보니 힙(우선순위큐)를 써야 하더라구요 ㅎㅎ 감사합니다!

// 가장 빈번한 k개의 수를 만들기 위해 우선순위 큐를 사용
// 시간복잡도: O(N log k), 공간복잡도: O(N)
for (int n: count.keySet()) {
heap.add(n);
if (heap.size() > k) heap.poll(); // 가장 빈번한 K개가 만족됐으니 더이상 추가하지 않고 제외
}

// k ~ 0 순서대로 힙에서 역순으로 뽑음
// 시간복잡도: O(k log k), 공간복잡도: O(N)
int[] result = new int[k];
for(int i = k - 1; i >= 0; --i){
result[i] = heap.poll();
}

return result;
}
}