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
34 changes: 34 additions & 0 deletions contains-duplicate/namuuCY.java

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🏷️ 알고리즘 패턴 분석

  • 패턴: Hash Map / Hash Set, Greedy
  • 설명: 집합(Set)을 이용해 이미 본 숫자를 빠르게 확인하는 방식으로 중복 여부를 판단한다. 각 원소를 순차적으로 확인하며, 이미 존재하면 즉시 종료하는 탐색 패턴이다.

📊 시간/공간 복잡도 분석

복잡도
Time O(n)
Space O(n)

피드백: 한 번의 순회로 각 숫자를 HashSet에 저장하며 중복 여부를 판단합니다.

개선 제안: 현재 구현이 적절해 보입니다.

💡 풀이에 시간/공간 복잡도를 주석으로 남겨보세요!

Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@


// 문제 이해
// - 주어진 숫자열에 여러 숫자가 주어지고,
// - 두 번 이상 동일한 숫자가 나온다면 true, 그렇지 않다면 false
//
//
// 문제 해결을 위한 의식의 흐름
// - 맨처음에는 숫자 범위가 작다면 count를 위한 array를 생각
// - 숫자 범위가 int 범위 가까이 된다면, 시공간 복잡도 초과
// - 기록하고, query 가 빠르게 이뤄지는 자료구조 필요
// - count를 위해 숫자를 굳이 저장할 필요가 없고, 존재하는지만 확인하면 된다.
// -> Set 자료구조 필요성
//
// 시공간 복잡도
// TC: O(N)
// SC: O(N)
// - nums의 length를 N 이라 하면,
// - 시간복잡도 : O(N) - N번 순회, 매 query별로 이론상 O(1)
// - 공간복잡도 : O(N)


class Solution {
public boolean containsDuplicate(int[] nums) {
Set<Integer> numberContainer = new HashSet<>();

for (int number : nums) {
if (numberContainer.contains(number)) return true;
numberContainer.add(number);
}

return false;
}
}
79 changes: 79 additions & 0 deletions house-robber/namuuCY.java

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🏷️ 알고리즘 패턴 분석

  • 패턴: Dynamic Programming, Greedy
  • 설명: 코드는 이웃 서브문제의 최댓값을 활용하는 DP 아이디어를 단순 순회로 구현한 예로, 한 칸 건너뜀과 누적 합의 최댓값을 유지하는 형태가 DP 패턴에 해당합니다. 또한 제약에 따라 선택과 비선택의 최대를 격리해 계산하는 모습은 그리디적 요소와도 연결됩니다.

📊 시간/공간 복잡도 분석

복잡도
Time O(n)
Space O(1)

피드백: 두 상태를 유지하며 이전 값을 이용해 현재 값을 갱신하는 방식으로 공간을 상수로 관리합니다.

개선 제안: 현재 구현이 적절해 보입니다.

💡 풀이에 시간/공간 복잡도를 주석으로 남겨보세요!

Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
// TC: O(N)
// SC: O(1)

class Solution {

// 문제 이해
// 1. 1자로 주욱 나열되어있는 집 : 인접한다는 것은 index가 1차이 난다는 것
// 2. 인접하는 두 집을 연속해서 털면 안된다.
// 3. 2의 제약조건을 가지고 털 수 있는 돈의 최대 합
//
// 문제 해결을 위한 의식의 흐름
// - 이거 예전에 백준에서 봤던 문제같음.
// - 어떤 한 집을 방문할 때, 앞 집이 털렸을 경우와 털리지 않았을 경우를 모두 고려해야함.
// - 맨 처음으로 DP를 생각하게 됨.
// - 털렸을 경우와 털리지 않았을 경우의 값을 모두 저장해놔야 할 것으로 생각
// - 2차원 배열 DP를 아래와 같이 정의한다면
// - DP[0-안털었다 or 1-털었다][index] = index번째 집까지 왔을때 훔친 돈의 총합
// 1. 총합이므로 자료형은 int 만으로 충분? long 배열써야하는지?
// - nums[i]가 최대 400이고, nums 길이가 100 이하 이므로 int로도 충분
// 2. DP 채워지는건 어떻게? 점화식
// - i번째 집을 방문할 때
// - i번째 집을 턴다고 가정 : i - 1 번째 집은 털지 않은 상태 + 현재 집의 돈
// - i번째 집을 털지 않는다고 가정 : i - 1 번째 집은 털어도 되고, 털지 않아도 됨 두 개중 최댓값
// 3. 이렇게 DP를 정의할 경우, DAG인가?
// - i번째 집의 정보는 i-1번째 집의 정보로부터만 오기 때문에 DAG이다.
// - 엣지케이스? :
// - 맨 처음 index
// DP[0][0] = 0 / 0이면 더하지 않고,
// DP[0][0] = nums[0] / 1이면 더한다
// - 길이가 1이면?
// - 쓰다보니 느낀건데 어차피 이전 집의 값만 필요하니까 굳이 DP를 사용안해도 될 것 같은데?
// - 이렇게 하면 array 로 데이터 저장할 필요 X
//
//
// 시공간복잡도
// N : nums의 길이
// - DP 풀이 :
// - 시간 복잡도 : O(N)
// - 공간 복잡도 : O(N) // N * 2 개만큼 저장해야함.
// - DP X 풀이 :
// - 시간 복잡도 : O(N)
// - 공간 복잡도 : O(1) // 이전 값 2개만 저장하면 됨.
//


/*
DP 풀이
public int rob(int[] nums) {
int[][] DP = new int[2][nums.length];
DP[1][0] = nums[0];

for (int idx = 1 ; idx < nums.length; idx ++) {
DP[1][idx] = DP[0][idx - 1] + nums[idx];
DP[0][idx] = Math.max(DP[0][idx - 1], DP[1][idx - 1]);
}

return Math.max(DP[0][nums.length - 1], DP[1][nums.length - 1]);
}
*/

// DP X, 일반 순회 풀이
public int rob(int[] nums) {
int robbed = 0;
int unrobbed = 0;

int prevRobbed;
int prevUnrobbed;

for (int money : nums) {
prevRobbed = robbed; // 0 1 2 4
prevUnrobbed = unrobbed; // 0 0 1 2

robbed = prevUnrobbed + money; // 1 2 4 3
unrobbed = Math.max(prevUnrobbed, prevRobbed); // 0 1 2 4
}

return Math.max(robbed, unrobbed);
}
}
33 changes: 33 additions & 0 deletions longest-consecutive-sequence/namuuCY.java

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🏷️ 알고리즘 패턴 분석

  • 패턴: Sort, Two Pointers, Dynamic Programming
  • 설명: 배열 정렬 후 연속 증가 구간을 탐색하는 흐름으로, 인접 원소 비교로 연속 수를 세는 방식이다. 직접적인 DP/슬라이딩 윈도우보다는 정렬 기반의 탐색 패턴에 가깝다.

📊 시간/공간 복잡도 분석

복잡도
Time O(n log n)
Space O(1)

피드백: 정렬이 필요하므로 시간복잡도는 n log n이며, 추가 배열 없이 상수 공간으로 구현합니다.

개선 제안: 현재 구현이 적절해 보입니다.

💡 풀이에 시간/공간 복잡도를 주석으로 남겨보세요!

Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
// 문제 풀이 흐름
// 오름차순 sort 후에 현재 보고 있는 숫자가 이전 숫자와
// 같으면 count 유지
// 1차이나면 count 증가
// 이외에는 count 초기화 및 이전 count 최댓값 비교

// N = nums.length 라 할때
// 시간복잡도 : O(N logN)
// 공간복잡도 : O(N)

class Solution {
public int longestConsecutive(int[] nums) {
Arrays.sort(nums);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

HashSet 을 활용하면 정렬 없이 O(N) 시간 복잡도로 풀이할 수 있습니다.


if (nums.length == 0) return 0;

int maxSequenceLength = 0;
int currentLength = 1;

for (int i = 1 ; i < nums.length; i ++) {
if (nums[i] == nums[i - 1]) continue;
if (nums[i] == nums[i - 1] + 1) {
currentLength ++;
continue;
}

maxSequenceLength = Math.max(maxSequenceLength, currentLength);
currentLength = 1;
}

return Math.max(maxSequenceLength, currentLength);
}
}
32 changes: 32 additions & 0 deletions top-k-frequent-elements/namuuCY.java

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🏷️ 알고리즘 패턴 분석

  • 패턴: Hash Map / Hash Set, Sorting
  • 설명: 숫자 빈도수 저장에 HashMap을 사용하고, 빈도수를 기준으로 내림차순 정렬하여 상위 k개를 추출하는 흐름으로 구성되어 있어 Hash Map과 Sorting 패턴이 모두 해당됩니다.

📊 시간/공간 복잡도 분석

복잡도
Time O(n log n)
Space O(n)

피드백: 빈도 수를 키로 하는 맵과 그 키들로 구성된 리스트를 정렬해 상위 k개를 선택합니다.

개선 제안: 현재 구현이 적절해 보입니다.

💡 풀이에 시간/공간 복잡도를 주석으로 남겨보세요!

Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
// 문제 풀이 흐름
// 각 숫자가 몇개가 나왔는지 계속해서 저장하고, 바로 확인할 수 있는 자료구조가 필요
// -> HashMap

// N = nums.length 라 할때
// 시간복잡도 : O(NlogN)
// 공간복잡도 : O(N)

class Solution {
public int[] topKFrequent(int[] nums, int k) {
Map<Integer, Integer> numberCount = new HashMap<>();

for (int number : nums) {
int countOfCurrentNumber = numberCount.getOrDefault(number, 0);
numberCount.put(number, countOfCurrentNumber + 1);
}

List<Integer> numbers = new ArrayList<>(numberCount.keySet());

numbers.sort((first, second) ->
Integer.compare(numberCount.get(second), numberCount.get(first))
);
Comment on lines +18 to +22

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

정렬 대신 빈도수를 배열 인덱스로 활용하는 버킷 정렬을 쓰면 시간 복잡도를 O(NlogN)에서 O(N)으로 줄일 수 있습니다.
빈도수의 최댓값은 배열 길이 N 을 넘지 않으므로, List[] buckets = new List[nums.length + 1] (혹은, 빈도수의 최대값 만큼)을 선언해 빈도별로 숫자를 담은 뒤, 역순으로 K 개를 꺼내면 정렬 없이 빠르게 처리할 수 있어 제안해 드립니다.


int[] answer = new int[k];

for (int i = 0 ; i < k ; i ++) {
answer[i] = numbers.get(i);
}

return answer;
}
}
25 changes: 25 additions & 0 deletions two-sum/namuuCY.java

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🏷️ 알고리즘 패턴 분석

  • 패턴: Hash Map / Hash Set, Two Pointers
  • 설명: 해당 코드는 한 번 순회하며 해시맵으로 이미 본 수의 인덱스를 기록하고, 현재 수와 타깃의 차가 이미 존재하는지 확인하는 방식으로 해결합니다. 이때 해시 맵을 이용한 조회-저장 패턴이 핵심이며, 두 수의 합을 찾는 문제의 대표적인 키워드입니다.

📊 시간/공간 복잡도 분석

복잡도
Time O(n)
Space O(n)

피드백: 해시맵으로 이미 본 값의 인덱스를 저장하고, 필요한 값을 만날 때 쌍을 즉시 반환합니다.

개선 제안: 현재 구현이 적절해 보입니다.

💡 풀이에 시간/공간 복잡도를 주석으로 남겨보세요!

Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// 문제 풀이 흐름
// target이 고정되어있고, 이 target에서 현재 값을 뺀게 존재하는지를 확인해야함.
// 존재한다면, 그 값의 인덱스를 바로 알아야 함.
// hashmap을 사용

// N = nums.length 라 하면
// 시간복잡도 : O(N)
// 공간복잡도 : O(N)

class Solution {
public int[] twoSum(int[] nums, int target) {
Map<Integer, Integer> numberCount = new HashMap<>();

for (int i = 0 ; i < nums.length; i ++) {
int val = target - nums[i];
if (numberCount.containsKey(val)) {
return new int[]{i, numberCount.get(val)};
}

numberCount.put(nums[i], i);
}

return null;
}
}
Loading