Skip to content

[김성재] 3주차 제출합니다. #24

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
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
98 changes: 98 additions & 0 deletions week-03/climbing-stairs/seongjae.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
# Intuition
첫 번째 시도에서는 가능한 모든 조합의 수를 계산하려고 했음.
n개의 계단을 오를 때 1칸씩 오르는 방법과 2칸씩 오르는 방법을 섞어서 몇 가지 경우가 나오는지 세는 방식.

# Approach
1. 계단을 2칸씩 오를 수 있는 최대 횟수를 구함.
2. 2칸씩 오르는 횟수를 0부터 최대 횟수까지 증가시키면서, 남은 계단을 1칸씩 오르는 경우를 계산.
3. 각 경우의 수를 조합 계산(combination)을 통해 구함.

# Complexity
- Time complexity: O(n^2)
조합 계산을 위해 팩토리얼 계산이 포함됨

- Space complexity: O(1)
추가 메모리 사용 없음

# Code
스택 오버플로우
```java
public class ClimbingStairs70 {
public int climbStairs(int n) {
int cases = 0;
int maxTwos = n / 2;
for (int i = 0; i <= maxTwos; i++) {
int countOnes = n - 2 * i;
cases += combination(countOnes + i, i);
}
return cases;
}

private int combination(int n, int k) {
return factorial(n) / (factorial(k) * factorial(n - k));
}

private int factorial(int n) {
if (n == 0 || n == 1)
return 1;
else
return factorial(n-1) * n;
}
}
```

# Learned
팩토리얼 계산을 재귀로 하면 큰 숫자에서 스택 오버플로우 발생 가능해서
비효율적일 수 있다는 것을 배웠음


# Intuition
두 번째 시도에서는 반복문을 사용하여 가능한 모든 조합을 계산함.
더 효율적이고 안정적인 방법을 사용함.

# Approach
1. 2칸씩 오를 수 있는 최대 횟수를 구함.
2. 각 경우에 대해 조합(combination)을 반복문으로 계산.
3. 조합 계산 시 k와 n-k 중 작은 값을 선택하여 계산을 최적화함.

# Complexity
- Time complexity: O(n)
조합 계산이 더 효율적임

- Space complexity: O(1)
추가 메모리 사용 없음


# Code
Runtime: 0ms Memory Usage: 40.1MB
```java
public class ClimbingStairs70 {
public int climbStairs(int n) {
int maxTwos = n / 2;
long cases = 0;
for (int i = 0; i <= maxTwos; i++) {
int countOnes = n - 2 * i;
cases += combination(countOnes + i, i);
}
return (int)cases;
}

private long combination(int n, int k) {
if (k == 0 || k == n) {
return 1;
}
if (k > n - k) {
k = n - k; // nCk = nC(n-k)
}
long result = 1;
for (int i = 0; i < k; i++) {
result *= (n - i);
result /= (i + 1);
}
return result;
}
}
```

# Learned
반복문을 사용하여 조합을 계산하면 재귀보다 효율적이고 안정적일 수 있음.
42 changes: 42 additions & 0 deletions week-03/maximum-depth-of-binary-tree/seongjae.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# Intuition
이 문제는 이진 트리의 최대 깊이를 구하는 문제임.
재귀적으로 각 노드의 자식 노드들을 탐색하여 최대 깊이를 계산함.

# Approach
1. 기저 사례로, 현재 노드가 null인 경우 0을 반환.
2. 현재 노드가 리프 노드인 경우 1을 반환.
3. 그렇지 않은 경우, 왼쪽 서브트리와 오른쪽 서브트리의 깊이를 재귀적으로 계산한 후, 두 값 중 큰 값에 1을 더하여 반환.

# Complexity
- Time complexity: O(n)
트리의 모든 노드를 한 번씩 방문하기 때문.

- Space complexity: O(h)
재귀 호출의 깊이 때문에, h는 트리의 높이.

# Code
Runtime: 0ms Memory Usage: 42.6MB
```java
// 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;
// }
// }
public class MaximumDepthOfBinaryTree104 {
public int maxDepth(TreeNode root) {
if (root == null) return 0;
if (root.left == null && root.right == null) return 1;
return Math.max(maxDepth(root.left), maxDepth(root.right)) + 1;
}
}
```

# Learned
재귀를 사용하여 이진 트리의 최대 깊이를 계산하는 방법을 익혔음.
43 changes: 43 additions & 0 deletions week-03/meeting-rooms/seongjae.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# Intuition
회의가 서로 겹치는지 확인하기 위해 회의를 시작 시간 기준으로 정렬한 후, 이전 회의의 끝나는 시간과 다음 회의의 시작 시간을 비교하

# Approach
1. 회의를 시작 시간 기준으로 정렬.
2. 각 회의를 순서대로 확인하면서, 이전 회의의 끝나는 시간과 현재 회의의 시작 시간을 비교.
3. 만약 현재 회의의 시작 시간이 이전 회의의 끝나는 시간보다 빠르면, 겹친다고 판단하고 false를 반환.
4. 모든 회의를 확인했을 때 겹치는 회의가 없으면 true를 반환.

# Complexity
- Time complexity: O(n log n)
회의 시간을 정렬하는 데 걸리는 시간.

- Space complexity: O(1)
추가적인 메모리 사용이 거의 없음.


# Code
Runtime: ms Memory Usage: MB
```java
// public class Interval {
// int start, end;
// Interval(int start, int end) {
// this.start = start;
// this.end = end;
// }
// }
public class MeetingRooms920lintcode {
public boolean canAttendMeetings(List<Interval> intervals) {
int end = 0;
for(Interval interval : intervals) {
if (interval.start >= end) return false;
else {
end = interval.end;
}
}
return true;
}
}
```

# Learned
중국 사이트는 가입이 안되고 릿은 유료라 돌려보지 못했다.. 맞는지 모르겠다.
46 changes: 46 additions & 0 deletions week-03/same-tree/seongjae.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
# Intuition
이 문제는 두 이진 트리가 같은지 확인하는 문제임.
이를 위해 각 노드를 재귀적으로 비교하면 됨.

# Approach
1. 두 트리의 루트 노드부터 비교를 시작함.
2. 두 노드가 모두 null이면 true를 반환.
3. 한 노드만 null이면 false를 반환.
4. 두 노드의 값이 다르면 false를 반환.
5. 두 노드의 값이 같으면, 왼쪽 자식 노드와 오른쪽 자식 노드를 각각 재귀적으로 비교.

# Complexity
- Time complexity: O(n)
트리의 모든 노드를 한 번씩 방문하기 때문.

- Space complexity: O(h)
재귀 호출의 깊이 때문에, h는 트리의 높이.


# Code
Runtime: 0ms Memory Usage: 40.7MB
```java
// 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;
// }
// }
public class SameTree {
public boolean isSameTree(TreeNode p, TreeNode q) {
if (p == null && q == null) return true;
if (p == null || q == null) return false;
if (p.val != q.val) return false;
return isSameTree(p.left, q.left) && isSameTree(p.right, q.right);
}
}
```

# Learned
두 이진 트리가 동일한지 확인하기 위해 재귀적으로 각 노드를 비교하는 방법을 익혔음.
51 changes: 51 additions & 0 deletions week-03/subtree-of-another-tree/seongjae.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
# Intuition
주어진 트리의 각 노드에서 시작해 두 트리가 동일한지 확인

# Approach
1. 트리의 루트 노드부터 시작해, 각 노드를 순회하면서 부분 트리인지 확인.
2. 현재 노드가 부분 트리의 루트 노드와 동일한지 확인.
3. 동일하면, 두 트리가 동일한지 재귀적으로 확인.
4. 동일하지 않으면, 왼쪽 및 오른쪽 자식 노드에서 다시 부분 트리인지 확인.

# Complexity
- Time complexity: O(n * m)
n은 주어진 트리의 노드 수, m은 부분 트리의 노드 수. 최악의 경우 모든 노드에서 부분 트리 확인.

- Space complexity: O(h)
재귀 호출의 깊이 때문에, h는 주어진 트리의 높이.


# Code
Runtime: 2ms Memory Usage: 44.5MB
```java
// 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;
// }
// }
public class SubtreeOfAnotherTree572 {
public boolean isSubtree(TreeNode root, TreeNode subRoot) {
if (root == null && subRoot == null) return true;
if (root == null || subRoot == null) return false;
if (root.val == subRoot.val) return isContainTree(root, subRoot);
return isSubtree(root.left, subRoot) || isSubtree(root.right, subRoot);
}

public boolean isContainTree(TreeNode p, TreeNode q) {
if(p == null || q == null);
if (p.val != q.val) return false;
return isContainTree(p.left, q.left) && isContainTree(p.right, q.right);
}
}
```

# Learned
두 트리 중 하나가 다른 트리의 부분 트리인지 확인하는 방법을 배웠음.
각 노드를 순회하면서 부분 트리의 루트 노드와 동일한지 확인하고, 동일하면 두 트리가 동일한지 재귀적으로 확인하는 것이 중요함.