diff --git a/graph-valid-tree/dev-jonghoonpark.md b/graph-valid-tree/dev-jonghoonpark.md new file mode 100644 index 000000000..8706d4675 --- /dev/null +++ b/graph-valid-tree/dev-jonghoonpark.md @@ -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)이다. 시간 복잡도를 조금 더 디테일 하게 보자면 간선 의 수도 포함을 시킬 수 있을 것이다. diff --git a/house-robber-ii/dev-jonghoonpark.md b/house-robber-ii/dev-jonghoonpark.md new file mode 100644 index 000000000..34e9405c7 --- /dev/null +++ b/house-robber-ii/dev-jonghoonpark.md @@ -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) 이다. diff --git a/house-robber/dev-jonghoonpark.md b/house-robber/dev-jonghoonpark.md new file mode 100644 index 000000000..b59b0364f --- /dev/null +++ b/house-robber/dev-jonghoonpark.md @@ -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) 이다. diff --git a/longest-palindromic-substring/dev-jonghoonpark.md b/longest-palindromic-substring/dev-jonghoonpark.md new file mode 100644 index 000000000..5bfe6f7c3 --- /dev/null +++ b/longest-palindromic-substring/dev-jonghoonpark.md @@ -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)이다. + +빅오 표기법 상으로도 개선이 된 방식이다. 실제로 시간도 더 단축되었다. diff --git a/number-of-connected-components-in-an-undirected-graph/dev-jonghoonpark.md b/number-of-connected-components-in-an-undirected-graph/dev-jonghoonpark.md new file mode 100644 index 000000000..d8701ef19 --- /dev/null +++ b/number-of-connected-components-in-an-undirected-graph/dev-jonghoonpark.md @@ -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 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 edges; + + public Vertex(int id) { + this.id = id; + this.edges = new ArrayList<>(); + } +} +``` + +### TC, SC + +Vertex 의 수를 V, Edge 의 수를 E 라고 하였을 때, +시간 복잡도는 O(V + E), 공간 복잡도는 O(V + E) 이다.