Skip to content
Open
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
35 changes: 35 additions & 0 deletions 3sum/essaysir.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.

🏷️ 알고리즘 패턴 분석

  • 패턴: Brute Force, Hash Map / Hash Set
  • 설명: 세 가지 수의 모든 조합을 나열하고 합이 0인 경우를 걸러내는 방식으로, 문제의 해를 모두 탐색하는 brute-force 패턴에 더해 중복 제거를 위해 Hash Set을 활용합니다.

📊 시간/공간 복잡도 분석

복잡도
Time O(n^3)
Space O(n^2)

피드백: 전체 가능한 3중 루프를 통해 경우를 모두 나열한 뒤 합이 0인 경우를 Set에 저장하므로 비효율적이다. 중복 제거는 LinkedHashSet으로 수행되나 시간은 급격히 증가한다.

개선 제안: 고려해볼 만한 대안: 투 포인터를 이용한 정렬 후 O(n^2) 알고리즘으로 구현하여 시간 복잡도를 크게 낮출 수 있다.

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

Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import java.util.*;

class Solution {
public List<List<Integer>> threeSum(int[] nums) {
int n = nums.length;
Arrays.sort(nums);

Set<List<Integer>> result = new LinkedHashSet<>();

// N C 3 조합 전부 나열
List<List<Integer>> possible = new ArrayList<>();
for (int i = 0; i < n; i++) {
for (int j = i + 1; j < n; j++) {
for (int k = j + 1; k < n; k++) {
possible.add(Arrays.asList(nums[i], nums[j], nums[k]));
}
}
}

// 합이 0인 것만 걸러서 Set에 넣기
for (int i = 0; i < possible.size(); i++) {
List<Integer> array = possible.get(i);
int sum = 0;
for (int cur : array) {
sum += cur;
}
if (sum == 0) {
result.add(array); // Set이라 중복은 알아서 걸러짐
}
}

// 3) 리턴할 때 List로 변환
return new ArrayList<>(result);
}
}
24 changes: 24 additions & 0 deletions climbing-stairs/essaysir.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.

제 생각에 dfs 함수에 적절한 cache만 추가해도 시간복잡도가 엄청나게 좋아질것 같네요 ( O(N) )!

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

한 번 그렇게 수정해보도록 하겠습니다!! 감사합니다!!

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.

오 이제 적절한 시간복잡도네요!
정답이 피보나치 수열인것까지 아신다면 공간복잡도도 훨씬 줄이실수 있으실것 같아요!
고생하셨습니다.

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.

이런 DP를 쓰는 문제의 경우 Top-down이 생각해내긴 훨씬 쉽지만 몇몇 문제들은 시간제한이 애매하게 걸려 있어서
재귀 호출할때 오버헤드가 생기는것 때문에 TLE가 될수도 있기 때문에
Bottom-up으로 변환하는것도 연습해보시면 좋을거에요!

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, Hash Map / Hash Set
  • 설명: 코드가 재귀로 피보나치 형태의 중복 부분 문제를 해결하며, memoization으로 결과를 저장해 다이나믹 프로그래밍 패턴을 사용합니다. 해시맵을 이용해 이미 계산한 값을 caching합니다.

📊 시간/공간 복잡도 분석

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

피드백: 메모화를 통해 중복 계산을 제거했지만 재귀 호출로 깊이가 커지면 스택오버플로가 발생할 수 있다.

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

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

Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import java.util.*;

class Solution {
// TC: O(2의 N승)
// SC: O(N)
public static Map<Integer, Integer> memo = new HashMap<>();

public int climbStairs(int n) {
// 1과 2로만 움직일 수 있을 때, 도달할 수 있는 모든 방법의 수에 대해 구하시오
// DPS (QUEUE) , BPS (STACK)
return dfs(n);
}

// dfs(5) -> dfs(3) + dfs(4) -> dfs(2) + dfs(1) + dfs(3) + dfs(2)
public static int dfs(int n){
if ( n == 1) return 1;
if ( n == 2) return 2;
if ( memo.containsKey(n) ) return memo.get(n);

int result = dfs(n-1) + dfs(n-2);
memo.put(n, result);
return result;
}

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.

전 DP로 풀었는데 재귀로도 접근할 수 있겠네요!

단순한거지만 아래처럼 쓰면 단순해질 것 같아요!

        if ( n <= 2) return n;

}
26 changes: 26 additions & 0 deletions product-of-array-except-self/essaysir.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.

🏷️ 알고리즘 패턴 분석

  • 패턴: Greedy, Division
  • 설명: 배열 원소의 곱을 각 위치에서 나누어 구하는 방식은 분할 없이 전체 곱을 한 번 계산한 뒤 각 원소로 나누는 아이디어로, 탐색이나 최적화보다는 값의 조합 규칙에 의존하는 패턴입니다. 또한 0 처리 로직이 조건 분기로 구성되어 있어 간접적으로 Greedy 성격의 선택적 판단이 포함됩니다.

📊 시간/공간 복잡도 분석

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

피드백: 0의 개수에 따른 분기 처리로 0이 다수 있을 때도 올바르게 동작한다.

개선 제안: 0 제거 없이 좌우 누적 곱을 두 배열로 구해도 동일한 시간복잡도를 가지나, 출력 공간은 동일하게 유지된다.

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

Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
class Solution {
public int[] productExceptSelf(int[] nums) {
// 시간 복잡도가 O(N) 이어야 함.
// 배열에서 나 자신을 빼고서 모두를 곱하라
// 어떻게 해야 시간 복잡도가 O(N) 이지 ?
int n = nums.length;
int zeroCount = 0;
int maxTotal = 1; // 0이 아닌 값들의 곱
for (int x : nums) {
if (x == 0) zeroCount++;
else maxTotal *= x;
}

int[] result = new int[n];
for (int i = 0; i < n; i++) {
if (zeroCount >= 2) {
result[i] = 0; // 0이 2개 이상 → 무조건 0
} else if (zeroCount == 1) {
result[i] = (nums[i] == 0) ? maxTotal : 0; // 0 위치만 살아남음
} else {
result[i] = maxTotal / nums[i]; // 0 없음 → 그냥 나눔
}
}
return result;
}
Comment on lines +2 to +25

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.

나중에 기회되시면 나눗셈 없이 푸는 방법도 한 번 고민해보시면 좋을 것 같습니다!
곱하기로만 푸는 방법이 참신하더라구요!

}
20 changes: 20 additions & 0 deletions valid-anagram/essaysir.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
  • 설명: 두 문자열의 문자 빈도수를 해시 맵으로 비교하는 방식으로 아나그램 여부를 판단한다. 각 문자 등장 횟수를 맵에 누적하고 최종적으로 두 맵의 동일성으로 결과를 도출한다.

📊 시간/공간 복잡도 분석

복잡도
Time O(n + m)
Space O(k)

피드백: 두 맵을 비교하는 단순 구현으로 직관적이지만, 배열 차원으로 최적화 가능하다.

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

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

Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import java.util.*;

class Solution {
public boolean isAnagram(String s, String t) {
// 둘이 anagram 이면 인지 아닌지 확인 해라
// 아나 그램이 다시 만들 수 있는 가 == 들어있는 알파벳의 갯수가 동일한 가
Map<Character,Integer> prevMap = new HashMap<>();
Map<Character,Integer> curMap = new HashMap<>();

for ( int i = 0; i < s.length(); i++ ){
prevMap.merge(s.charAt(i), 1, Integer::sum);
}

for ( int i = 0; i < t.length(); i ++){
curMap.merge(t.charAt(i),1 ,Integer::sum);
}

return prevMap.equals(curMap);
}
Comment on lines +4 to +19

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.

약간의 성능 개선인데 맨 처음 s와 t의 길이가 다른 경우, 조기 종료할 수도 있습니다!

평소 파이썬으로 풀다가 요즘 자바로 푸려고 하고 있는데 풀이 배워갑니다👍

}
27 changes: 27 additions & 0 deletions validate-binary-search-tree/essaysir.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.

🏷️ 알고리즘 패턴 분석

  • 패턴: Binary Search, Divide and Conquer
  • 설명: BST 유효성 검사를 재귀적으로 수행하며, 각 노드에 대해 허용 범위를 좁혀가며(left<값<right) 올바른 이진 탐색 트리인지 확인한다. 분할하여 문제를 부분 문제로 해결하는 방식으로 구현된 패턴이다.

📊 시간/공간 복잡도 분석

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

피드백: 전형적인 최소-와 최대 범위 검사를 통해 문제를 해결한다. 음수/양수 경계도 안전하게 처리한다.

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

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

Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
public boolean isValidBST(TreeNode root) {
return validate(root, Long.MIN_VALUE, Long.MAX_VALUE);
}

private boolean validate(TreeNode node, long low, long high) {
if (node == null) return true;
if (node.val <= low || node.val >= high) return false;
return validate(node.left, low, node.val)
&& validate(node.right, node.val, high);
}
}
Loading