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

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.

🏷️ 알고리즘 패턴 분석

  • 패턴: Divide and Conquer
  • 설명: 이 코드는 전위(preorder)와 중위(inorder) 순회 배열을 이용해 재귀적으로 트리를 분할하며 구성하는 방식으로, 분할 정복 패턴을 따릅니다.

📊 시간/공간 복잡도 분석

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

피드백: 현재 구현은 inorder 배열에서 루트 노드 위치를 찾기 위해 선형 탐색을 수행하여, 최악의 경우 전체 배열 크기만큼 반복하므로 시간 복잡도가 O(n^2)입니다. 이를 개선하려면 inorder 값의 인덱스를 미리 맵에 저장하여 O(1) 탐색으로 변경하는 방법이 있습니다.

개선 제안: 고려해볼 만한 대안: inorder 값의 인덱스를 미리 해시맵에 저장하여 탐색 시간을 O(1)로 줄이면 전체 시간 복잡도를 O(n)으로 개선할 수 있습니다.

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

Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
/**
* 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 TreeNode buildTree(int[] preorder, int[] inorder) {
/**
1.preorder, inorder array를 기반으로 binary tree return
2.constraints
- 모두 unique values
- length min = 1, max = 3000
3.solutions
- Root node = preorder[0]
- inorder 에서 root node 위치 찾기 -> root node 위치 left/right node
- inorder 에서 구한 left/right node 수로 preorder array 에서 left/right 나눔

*/

return buildTree(preorder, 0, preorder.length - 1,
inorder, 0, inorder.length - 1);

}
private TreeNode buildTree(int[] preorder, int preStart, int preEnd,
int[] inorder, int inStart, int inEnd) {
if(preStart > preEnd || inStart > inEnd) return null;

//preorder 첫번째 값 = root node value
int rootVal = preorder[preStart];
TreeNode root = new TreeNode(rootVal);

//inorder 에서 root 찾기
int rootIndex = 0;
for(int i = 0; i<inorder.length; i++) {
if(inorder[i] == rootVal) {
rootIndex = i;
break;
}
}
//num of left subtree node
int leftSize = rootIndex - inStart;
root.left = buildTree(preorder, preStart+1, preStart + leftSize,
inorder, inStart, rootIndex - 1);

root.right = buildTree(preorder, preStart+leftSize+1, preEnd,
inorder, rootIndex + 1, inEnd);

return root;
}
}
44 changes: 44 additions & 0 deletions longest-palindromic-substring/hyeri0903.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.

🏷️ 알고리즘 패턴 분석

  • 패턴: Two Pointers, Expand around center
  • 설명: 이 코드는 문자열의 양쪽으로 확장하며 팰린드롬을 찾는 방식으로, 두 포인터를 활용하는 패턴과 확장 중심 탐색을 사용합니다.

📊 시간/공간 복잡도 분석

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

피드백: 이 구현은 각 중심마다 확장하는 방식으로, 최대 O(n^2)의 시간 복잡도를 갖습니다. 공간은 상수 공간을 사용하며, 팰린드롬 확장 과정에서 별도 저장 공간이 필요 없습니다.

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

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

Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
class Solution {
public String longestPalindrome(String s) {
/**
1.문제: 가장 긴 팰린드롬 string 찾기.
2.조건:
- s 문자열 길이 최소 1, 최대 1000
- 답이 1개가 아닐수도있음. 여러개중 1개만 반환해도 ok
- s 는 digit, English letters 로 구성
3.풀이
- stack 사용 -> TLE 발생
- expand around center (각 중심에서 양쪽으로 확장하여 체크)
- 길이 = 1 이면 바로 return
Palindrome은 substring 기준이라 전체 문자열 길이와 무관하게 홀수/짝수 케이스가 모두 존재할 수 있기 때문에, 두 경우를 모두 확인해야 합니다.

Time: O(n²) -> palindrome method 에서 최대 n 번 돌 수 있으므로

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.

저는 이 문제 풀지 못하고 Editorial을 참고했는데, 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.

O(n) 풀이 방법도 살펴봐야겠네요. 피드백 감사합니다!
@hwi-middle 님도 수고 많으셨습니다~!

Space: O(1)
*/

int n = s.length();
if(n == 1) return s;
//가운데 문자에서 시작 e.g "babad" n = 5, answer = "b"
String answer = "";

for(int i = 0; i < n; i++) {
//홀수 e.g "b". 중심이 1개
String odd = palindrome(s, i, i);
//짝수 e.g. "ab". 중심이 2개
String even = palindrome(s, i, i + 1);

String longer = odd.length() > even.length() ? odd : even;
if(longer.length() > answer.length()) {
answer = longer;
}
}
return answer;
}
String palindrome(String s, int start, int end) {
while(start >= 0 && end < s.length() && s.charAt(start) == s.charAt(end)) {
start--;
end++;
}
return s.substring(start+1, end);
}
}
42 changes: 42 additions & 0 deletions rotate-image/hyeri0903.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.

🏷️ 알고리즘 패턴 분석

  • 패턴: Two Pointers, Matrix Transposition
  • 설명: 이 코드는 행을 뒤집기 위해 양 끝 포인터를 이동하는 Two Pointers 패턴과, 대각선 기준 행렬을 뒤집는 행렬 전치(transpose)를 활용하여 회전하는 방식을 사용합니다.

📊 시간/공간 복잡도 분석

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

피드백: 이 방법은 두 단계(전치와 행 뒤집기)를 통해 in-place로 90도 회전을 수행하며, 시간 복잡도는 행렬의 모든 원소를 한 번씩 방문하므로 O(n^2)입니다. 공간은 추가적인 배열 없이 수행됩니다.

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

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

Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
class Solution {
public void rotate(int[][] matrix) {
/**
1.90도 시계방향으로 회전한 matrix return
2.constraints : in-place 로 rotate 할 것
3.solution: 2단계 처리
1) 대각선 기준 뒤집기 transpose, matrix[i][j] => matrix[j][i]
2) 각 행 reverse
time complexity : O(n^2), space: O(1)
*/

int n = matrix.length;

//1.transpose
for(int i = 0; i < n; i++) {
for(int j = i+1; j < n; j++) {
int tmp = matrix[i][j];
matrix[i][j] = matrix[j][i];
matrix[j][i] = tmp;
}
}

//2.reverse each row
for(int i = 0; i < n; i++) {
reverse(matrix[i]);
}
}

void reverse(int[] row) {
int left = 0;
int right = row.length - 1;

while(left < right) {
int tmp = row[left];
row[left] = row[right];
row[right] = tmp;

left++;
right--;
}
}
}
46 changes: 46 additions & 0 deletions subtree-of-another-tree/hyeri0903.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.

🏷️ 알고리즘 패턴 분석

  • 패턴: Recursive
  • 설명: 이 코드는 재귀 호출을 이용하여 트리의 모든 노드를 탐색하며, 서브트리인지 여부를 재귀적으로 판단하는 방식입니다. 재귀는 트리 구조 탐색에 자주 사용됩니다.

📊 시간/공간 복잡도 분석

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

피드백: 이 구현은 각 노드마다 isSameTree를 호출하여, 최악의 경우 모든 노드에 대해 서브트리 검사를 수행하므로 시간 복잡도는 O(nm)입니다. 공간은 재귀 호출 스택에 따라 달라집니다.

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

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

Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
/**
* 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 isSubtree(TreeNode root, TreeNode subRoot) {
/**
1.root 트리의 subtree가 subRoot tree 이면 true 아니면 false return
2.constraints
- subRoot tree 가 존재하는데 거기에 자식 노드가 추가로 있으면 안됨
- 자기 자신 root tree = subRoot tree 일수도 있음
3.solution
- 재귀함수로 subTree 찾고 subRoot 의 트리와 동일한지 검사
- root 트리 노드 수 : n, subRoot 트리 노드 수 : m
- timeComplexity : O(nm)
*/
if(root == null) return false;

//먼저 트리가 동일한지 체크 -> left subTree check -> right subTree check
return isSameTree(root, subRoot)
|| isSubtree(root.left, subRoot)
|| isSubtree(root.right, subRoot);

}
private boolean isSameTree(TreeNode a, TreeNode b) {
//둘 다 null
if (a == null && b == null) return true;
//둘중 하나만 null
if (a == null || b == null) return false;
//값이 다른 경우
if(a.val != b.val) return false;
//현재 값이 다르면 왼쪽끼리, 오른쪽끼리 비교, 모두 같아야 true return
return isSameTree(a.left, b.left) && isSameTree(a.right, b.right);
}
}
Loading