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
  • 설명: 이 코드는 전위와 중위 순회 배열을 기반으로 재귀적으로 트리를 분할하여 구성하는 방식으로, 문제를 작은 부분으로 나누어 해결하는 Divide and Conquer 패턴에 속합니다.

📊 시간/공간 복잡도 분석

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

피드백: 매 재귀 호출마다 inorder 배열에서 루트 값을 찾기 위해 선형 탐색을 수행하므로 최악의 경우 O(n^2) 시간이 소요됩니다. 트리의 노드 수만큼 재귀 호출이 발생하며, 트리 구조에 따라 깊이와 공간 복잡도도 O(n)입니다.

개선 제안: 이진 탐색 트리 또는 해시맵을 활용하여 inorder 배열에서 루트 위치를 빠르게 찾는 방식을 고려하면 시간 복잡도를 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
  • 설명: 중심을 기준으로 좌우로 확장하는 방식으로 팰린드롬을 찾는 방법으로, 양 끝 포인터를 이동시키며 문자열을 확장하는 패턴입니다.

📊 시간/공간 복잡도 분석

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

피드백: 중심 확장 방법은 각 문자 또는 문자 쌍을 중심으로 확장하며 팰린드롬을 찾기 때문에, 문자열 길이 n에 대해 최대 O(n^2) 시간이 소요됩니다. 공간은 상수입니다.

개선 제안: 팰린드롬 확장 방식을 유지하면서, 불필요한 문자열 복사를 피하거나 Manacher's Algorithm을 적용하면 시간 복잡도를 O(n)으로 개선할 수 있습니다.

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

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 번 돌 수 있으므로
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);
}
}
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 검사를 수행하므로, 최악의 경우 n과 m이 각각 트리 노드 수일 때 시간 복잡도는 O(nm)입니다. 공간은 재귀 호출 스택에 따라 O(n)입니다.

개선 제안: 트리의 구조를 문자열로 직렬화하여 문자열 검색 알고리즘을 활용하면, 시간 복잡도를 개선할 수 있습니다.

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

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