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
46 changes: 46 additions & 0 deletions 3sum/j2h30728.ts

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.

🏷️ 알고리즘 패턴 분석

  • 패턴: Two Pointers, Sorting, Hash Map / Hash Set
  • 설명: 3sum에서 정렬 후 두 포인터(left, right)를 이동하며 합이 0인 경우를 찾는 전형적인 Two Pointers 패턴을 사용합니다. 중복 제거를 위한 조건도 포함되어 있어 O(n^2) 시간 복잡도와 O(1) 추가 공간으로 구현됩니다.

📊 시간/공간 복잡도 분석

유저 분석 실제 분석 결과
Time O(n^2) O(n^2)
Space O(1) O(1)

피드백: 정렬과 두 포인터를 이용해 중복 제거를 처리하고 있으며 평균적으로 O(n^2) 시간이 소요됩니다.

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

Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
/**
* 시간 복잡도 : O(n^2)
* 공간 복잡도 : O(1)
*/
function threeSum(nums: number[]): number[][] {
const result: number[][] = [];
nums.sort((a, b) => a - b);

for (let i = 0; i < nums.length - 2; i++) {
if (i > 0 && nums[i] === nums[i - 1]) {
continue;
}

if (nums[i] > 0) {
break;
}

let left = i + 1;
let right = nums.length - 1;

while (left < right) {
const sum = nums[i] + nums[left] + nums[right];

if (sum === 0) {
result.push([nums[i], nums[left], nums[right]]);

left++;
right--;

while (left < right && nums[left] === nums[left - 1]) {
left++;
}

while (left < right && nums[right] === nums[right + 1]) {
right--;
}
} else if (sum < 0) {
left++;
} else {
right--;
}
}
}

return result;
}
22 changes: 13 additions & 9 deletions climbing-stairs/j2h30728.ts

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, Two Pointers
  • 설명: 피보나치 계열의 합을 이용해 과거 값들로 현재 값을 구하는 방식으로, 중복 계산을 줄여 DP 패턴으로 해결한다. 순차적으로 이전 두 값을 유지하며 최적 해를 구하는 점이 특징이다.

📊 시간/공간 복잡도 분석

유저 분석 실제 분석 결과
Time O(n) O(n)
Space O(1) O(1)

피드백: 연속적인 합 문제를 두 변수로 유지하며 순차적으로 계산합니다.

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

Original file line number Diff line number Diff line change
@@ -1,14 +1,18 @@
/**
* 시간 복잡도 : O(n)
* 공간 복잡도 : O(1)
*/
function climbStairs(n: number): number {
if (n === 0 || n === 1) {
return 1;
}
if (n <= 2) return n;

const memo: number[] = [];
memo[0] = memo[1] = 1;
let prev2 = 1;
let prev1 = 2;
let current = 0;

for (let i = 2; i <= n; i++) {
memo[i] = memo[i - 1] + memo[i - 2];
for (let i = 3; i <= n; i++) {
current = prev2 + prev1;
prev2 = prev1;
prev1 = current;
}

return memo[n];
return current;
}
25 changes: 14 additions & 11 deletions product-of-array-except-self/j2h30728.ts

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.

🏷️ 알고리즘 패턴 분석

  • 패턴: Two Pointers, Greedy, Hash Map / Hash Set
  • 설명: 연속되는 두 포인터(left, right)를 이용해 각 위치의 곱을 구하는 패턴으로, 중간 배열 없이 좌우 누적 곱을 이용하는 방식이 핵심이다. 문제의 요구에 맞춰 한 방향에서의 누적을 다른 방향에서 곱해 최종 결과를 얻는 구조다.

📊 시간/공간 복잡도 분석

유저 분석 실제 분석 결과
Time O(n) O(n)
Space O(1) O(1)

피드백: 두 순회를 통해 추가 배열 없이 결과를 얻습니다.

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

Original file line number Diff line number Diff line change
@@ -1,18 +1,21 @@
/**
* 시간 복잡도 : O(n)
* 공간 복잡도 : O(1) (출력 배열 제외, left/right 변수만 사용)
*/
function productExceptSelf(nums: number[]): number[] {
const length = nums.length;
const result = new Array(nums.length).fill(1);
const arr = new Array(nums.length).fill(1);

let leftTemp = 1;
for (let i = 0; i < length; i++) {
result[i] = leftTemp;
leftTemp *= nums[i];
let left = 1;
for (let i = 0; i < nums.length; i++) {
arr[i] = left;
left *= nums[i];
}

let rightTemp = 1;
for (let i = length - 1; i >= 0; i--) {
result[i] *= rightTemp;
rightTemp *= nums[i];
let right = 1;
for (let i = nums.length - 1; i >= 0; i--) {
arr[i] *= right;
right *= nums[i];
}

return result;
return arr;
}
24 changes: 19 additions & 5 deletions valid-anagram/j2h30728.ts

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

공간 복잡도를 O(n)으로 적어주셨는데,
문제 조건에 s and t consist of lowercase English letters.라고 나와 있으니
Map에 저장되는 key 개수가 최대 26개라서 O(1)이 맞는 것 같습니다!

혹은 가능한 문자 집합의 크기를 k라고 본다면, 봇이 제안한 대로 O(k)도 맞는 표현인 듯합니다!

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
Member

Choose a reason for hiding this comment

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

저는 각각 따로 개수를 세서 비교하는 방식만 생각했는데,
하나는 증가시키고 다른 하나는 감소시켜서 최종 값이 0인지 확인하는 방법도 있었네요!

좋은 접근 방식 배워갑니다~

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, Greedy, Dynamic Programming
  • 설명: 두 문자열의 각 문자 빈도를 해시 맵으로 비교하는 방식으로 anagram 여부를 판단합니다. 입력 길이가 같고, 해시 맵을 이용해 문자 등장 횟수를 증가/감소시키는 방식은 해시 기반 카운팅 패턴에 해당합니다. 해당 코드는 다른 패턴보다 이 패턴이 가장 적합합니다.

📊 시간/공간 복잡도 분석

유저 분석 실제 분석 결과
Time O(n) O(n)
Space O(n) O(k)

피드백: 문자 빈도 맵을 사용해 각 문자 차이를 누적 비교합니다.

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

Original file line number Diff line number Diff line change
@@ -1,12 +1,26 @@
/**
*
* @param s
* @param t
* @returns
* 시간 복잡도 : O(n)
* 공간 복잡도 : O(n)
*/
function isAnagram(s: string, t: string): boolean {
const obj = {};
if (s.length !== t.length) return false;

const map = new Map<string, number>();

for (let i = 0; i < s.length; i++) {
obj[s[i]] = (obj[s[i]] || 0) + 1;
map.set(s[i], (map.get(s[i]) ?? 0) + 1);
map.set(t[i], (map.get(t[i]) ?? 0) - 1);
}

for (let i = 0; i < t.length; i++) {
obj[t[i]] -= 1;
for (let ch of map.values()) {
if (ch !== 0) {
return false;
}
}

return Object.values(obj).filter((value) => value !== 0).length === 0;
return true;
}
15 changes: 10 additions & 5 deletions validate-binary-search-tree/j2h30728.ts

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
  • 설명: BST 유효성 검사로 트리의 각 노드를 중위 값 범위로 재귀적으로 검증하는 패턴. 재귀를 이용한 Divide and Conquer 방식으로 트리 구조를 탐색한다.

📊 시간/공간 복잡도 분석

유저 분석 실제 분석 결과
Time O(n) O(n)
Space O(h) O(h)

피드백: 각 노드에 대해 허용 범위를 좁혀나가며 유효성 검사.

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

Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,19 @@ class TreeNode {
}
}

/**
* 시간 복잡도 : O(n) - 모든 노드를 한 번씩 방문
* 공간 복잡도 : O(h) - 재귀 호출 스택 깊이 (h는 트리 높이, 최악의 경우 O(n))
*/
function isValidBST(root: TreeNode | null): boolean {
function valid(node, min, max) {
if (!node) return true;
function validate(node: TreeNode | null, min: number, max: number): boolean {
if (node === null) return true;

if (node.val <= min || node.val >= max) return false;

return valid(node.left, min, node.val) && valid(node.right, node.val, max);
return (
validate(node.left, min, node.val) && validate(node.right, node.val, max)
);
}

return valid(root, -Infinity, Infinity);
return validate(root, -Infinity, Infinity);
}
Loading