Skip to content

[박종훈] 10주차 답안 제출 #163

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

Merged
merged 5 commits into from
Jul 7, 2024
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
47 changes: 47 additions & 0 deletions graph-valid-tree/dev-jonghoonpark.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
- 문제
- 유료: https://leetcode.com/problems/graph-valid-tree/
- 무료: https://www.lintcode.com/problem/178/
- 풀이: https://algorithm.jonghoonpark.com/2024/07/02/leetcode-261

## 내가 작성한 풀이

```java
public class Solution {
public boolean validTree(int n, int[][] edges) {
int[] degrees = new int[n];

for (int[] edge : edges) {
int largeOne = Math.max(edge[0], edge[1]);
if (degrees[largeOne] == 0) {
degrees[largeOne] += 1;
} else {
return false;
}
}

int zeroCount = 0;
for (int degree : degrees) {
if (degree == 0) {
zeroCount++;
}

if (zeroCount > 1) {
return false;
}
}

return zeroCount == 1;
}
}
```

다음과 같이 가정을 하고 풀었다.

- 루트를 제외한 모든 노드는 1개의 부모를 가진다.
- 루트는 부모를 가지지 않는다.

따라서 각 노드로 들어오는 수를 세어봤을 때 루트에는 들어오는 간선이 없어야 하며, 나머지 노드는 1개의 간선이 있어야 한다.

### TC, SC

시간 복잡도는 O(n)이다. 공간 복잡도는 O(n)이다. 시간 복잡도를 조금 더 디테일 하게 보자면 간선 의 수도 포함을 시킬 수 있을 것이다.
43 changes: 43 additions & 0 deletions house-robber-ii/dev-jonghoonpark.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
- 문제: https://leetcode.com/problems/house-robber-ii/
- 풀이: https://algorithm.jonghoonpark.com/2024/07/03/leetcode-213

## 내가 작성한 풀이

```java
public class Solution {
public int rob(int[] nums) {
if (nums.length == 1) {
return nums[0];
}

if (nums.length == 2) {
return Math.max(nums[0], nums[1]);
}

if (nums.length == 3) {
return Math.max(nums[2], Math.max(nums[0], nums[1]));
}


return Math.max(getMaxInRange(nums, 0, nums.length - 1), getMaxInRange(nums, 1, nums.length));
}

public int getMaxInRange(int[] nums, int start, int end) {
int[] dp = new int[nums.length];
int max;
dp[start] = nums[start];
dp[start + 1] = nums[start + 1];
dp[start + 2] = nums[start + 2] + nums[start];
max = Math.max(dp[start + 2], dp[start + 1]);
for (int i = start + 3; i < end; i++) {
dp[i] = Math.max(nums[i] + dp[i - 2], nums[i] + dp[i - 3]);
max = Math.max(max, dp[i]);
}
return max;
}
}
```

### TC, SC

시간 복잡도는 O(n), 공간 복잡도는 O(n) 이다.
39 changes: 39 additions & 0 deletions house-robber/dev-jonghoonpark.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
- 문제: https://leetcode.com/problems/house-robber/
- 풀이: https://algorithm.jonghoonpark.com/2024/07/03/leetcode-198

## 내가 작성한 풀이

```java
public class Solution {
public int rob(int[] nums) {
int[] dp = new int[nums.length];
int max = 0;

if (nums.length == 1) {
return nums[0];
}

if (nums.length == 2) {
return Math.max(nums[0], nums[1]);
}

if (nums.length == 3) {
return Math.max(nums[2] + nums[0], nums[1]);
}

dp[0] = nums[0];
dp[1] = nums[1];
dp[2] = nums[2] + nums[0];
max = Math.max(dp[2], dp[1]);
for (int i = 3; i < nums.length; i++) {
dp[i] = Math.max(nums[i] + dp[i - 2], nums[i] + dp[i - 3]);
max = Math.max(max, dp[i]);
}
return max;
}
}
```

### TC, SC

시간 복잡도는 O(n), 공간 복잡도는 O(n) 이다.
186 changes: 186 additions & 0 deletions longest-palindromic-substring/dev-jonghoonpark.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,186 @@
- 문제: https://leetcode.com/problems/longest-palindromic-substring/
- 풀이: https://algorithm.jonghoonpark.com/2024/07/01/leetcode-5

## brute force 방식 (beats 12.41%)

```java
class Solution {
public String longestPalindrome(String s) {
int start = 0;
int end = start;

String max = "";

char[] charArray = s.toCharArray();
while (true) {
if (end == s.length()) {
break;
}

if (charArray[start] == charArray[end]) {
int tempStart = start;
int tempEnd = end;

boolean isPalindrome = true;
while (tempEnd >= tempStart) {
if (charArray[tempStart] != charArray[tempEnd]) {
isPalindrome = false;
break;
}
if (tempStart == tempEnd) {
break;
}
tempStart = tempStart + 1;
tempEnd = tempEnd - 1;
}

if (isPalindrome) {
String temp = s.substring(start, end + 1);
if (temp.length() > max.length()) {
max = temp;
}
}
}

end++;
if (end == s.length()) {
start = start + 1;
end = start;
}

if (start == s.length()) {
break;
}
}

return max;
}
}
```

### TC, SC

시간 복잡도는 O(n^2)이고, 공간 복잡도는 O(n)이다.

## brute force 방식 개선 (beats 48.52%)

아래 부분이 부분이다.

```java
start = start + 1;
end = start + max.length();
```

다음 end 값을 `start + max.length()` 로 두어 연산을 많이 줄일 수 있었고 꽤 큰 차이가 발생된다.

```java
class Solution {
public String longestPalindrome(String s) {
int start = 0;
int end = start;

String max = "";

char[] charArray = s.toCharArray();
while (start < s.length() && end < s.length()) {
if (charArray[start] == charArray[end]) {
int tempStart = start;
int tempEnd = end;

boolean isPalindrome = true;
while (tempEnd >= tempStart) {
if (charArray[tempStart] != charArray[tempEnd]) {
isPalindrome = false;
break;
}
if (tempStart == tempEnd) {
break;
}
tempStart = tempStart + 1;
tempEnd = tempEnd - 1;
}

if (isPalindrome) {
String temp = s.substring(start, end + 1);
if(temp.length() > max.length()) {
max = temp;
}
end = end + 1;
} else {
if (s.indexOf(charArray[start], end) > -1) {
end = end + 1;
} else {
start = start + 1;
end = start + max.length();
}
}
} else {
end++;
if (end == s.length()) {
start = start + 1;
end = start + max.length();
}

if (start == s.length()) {
break;
}
}

if (end == s.length()) {
start = start + 1;
end = start + max.length();
}
}

return max;
}
}
```

### TC, SC

시간 복잡도는 O(n^2)이고, 공간 복잡도는 O(n)이다.

빅오 표기법 상으로는 동일하나, 실행 시간이 매우 단축되었다.

## best solution (beats 95.84%)

하나의 포인터를 사용하여, 각 문자를 중심으로 Palindrome 이 발생할 수 있는 케이스를 조사한다.

```java
class Solution {
public String longestPalindrome(String s) {
String max = "";

char[] charArray = s.toCharArray();
for (int i = 0; i < s.length(); i++) {
char currentChar = charArray[i];
int left = i;
int right = i;

while (right < s.length() - 1 && currentChar == charArray[right + 1]) {
right++;
}

while (left > 0 && right < s.length() - 1 && charArray[left - 1] == charArray[right + 1]) {
left--;
right++;
}

String temp = s.substring(left, right + 1);
if (temp.length() > max.length()) {
max = temp;
}
}

return max;
}
}
```

### TC, SC

시간 복잡도는 평균적으로 O(n)이다. palindrome 의 길이가 n 에 가까워질수록 시간 복잡도는 O(n^2) 에 가까워 진다.
공간 복잡도는 O(n)이다.

빅오 표기법 상으로도 개선이 된 방식이다. 실제로 시간도 더 단축되었다.
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
- 문제
- 유료: https://leetcode.com/problems/number-of-connected-components-in-an-undirected-graph/
- 무료: https://neetcode.io/problems/count-connected-components
- 풀이: https://algorithm.jonghoonpark.com/2024/07/03/leetcode-323

```java
public class Solution {
public int countComponents(int n, int[][] edges) {
Map<Integer, Vertex> vertexMap = new HashMap<>();
int lastGroupId = 0;

for (int[] edge : edges) {
Vertex v1 = vertexMap.getOrDefault(edge[0], new Vertex(edge[0]));
Vertex v2 = vertexMap.getOrDefault(edge[1], new Vertex(edge[1]));

v1.edges.add(v2);
v2.edges.add(v1);

vertexMap.put(edge[0], v1);
vertexMap.put(edge[1], v2);
}

for (int i = 0; i < n; i++) {
Vertex vertex = vertexMap.get(i);
if (vertex == null) {
lastGroupId++;
} else {
// 0 이 아닐 경우는 이미 탐색한 케이스므로 스킵
if (vertex.groupId == 0) {
lastGroupId++;
dfs(vertex, lastGroupId);
}
}
}

return lastGroupId;
}

public void dfs(Vertex vertex, int groupId) {
vertex.groupId = groupId;
for (Vertex connected : vertex.edges) {
if (connected.groupId == 0) {
dfs(connected, groupId);
}
}
}
}

class Vertex {
int id;
int groupId;
List<Vertex> edges;

public Vertex(int id) {
this.id = id;
this.edges = new ArrayList<>();
}
}
```

### TC, SC

Vertex 의 수를 V, Edge 의 수를 E 라고 하였을 때,
시간 복잡도는 O(V + E), 공간 복잡도는 O(V + E) 이다.