diff --git a/graph-valid-tree/bky373.java b/graph-valid-tree/bky373.java new file mode 100644 index 000000000..2533d2518 --- /dev/null +++ b/graph-valid-tree/bky373.java @@ -0,0 +1,42 @@ +/* + time: O(n + m), where n is the number of nodes and m is the number of edges in the graph. + space: O(n + m) + */ +class Solution { + + public boolean validTree(int n, int[][] edges) { + + if (edges.length != n - 1) { + return false; + } + + List> adjList = new ArrayList<>(); + for (int i = 0; i < n; i++) { + adjList.add(new ArrayList<>()); + } + for (int[] edge : edges) { + adjList.get(edge[0]) + .add(edge[1]); + adjList.get(edge[1]) + .add(edge[0]); + } + + Stack stack = new Stack<>(); + Set visited = new HashSet<>(); + stack.push(0); + visited.add(0); + + while (!stack.isEmpty()) { + int curr = stack.pop(); + for (int adj : adjList.get(curr)) { + if (visited.contains(adj)) { + continue; + } + visited.add(adj); + stack.push(adj); + } + } + + return visited.size() == n; + } +} diff --git a/house-robber-ii/bky373.java b/house-robber-ii/bky373.java new file mode 100644 index 000000000..200d167d5 --- /dev/null +++ b/house-robber-ii/bky373.java @@ -0,0 +1,33 @@ +/* + time: O(N) + time: O(1) + */ +class Solution { + + public int rob(int[] nums) { + if (nums.length == 0) { + return 0; + } + if (nums.length == 1) { + return nums[0]; + } + + return Math.max( + dp(nums, 0, nums.length - 2), + dp(nums, 1, nums.length - 1) + ); + } + + private static int dp(int[] nums, int start, int end) { + int maxOfOneStepAhead = nums[end]; + int maxOfTwoStepsAhead = 0; + + for (int i = end - 1; i >= start; --i) { + int curr = Math.max(maxOfOneStepAhead, maxOfTwoStepsAhead + nums[i]); + + maxOfTwoStepsAhead = maxOfOneStepAhead; + maxOfOneStepAhead = curr; + } + return maxOfOneStepAhead; + } +} diff --git a/house-robber/bky373.java b/house-robber/bky373.java new file mode 100644 index 000000000..d225b039f --- /dev/null +++ b/house-robber/bky373.java @@ -0,0 +1,23 @@ +/* + time: O(N) + space: O(1) + */ +class Solution { + + public int rob(int[] nums) { + if (nums.length == 0) { + return 0; + } + + int maxOfTwoStepsAhead = 0; + int maxOfOneStepAhead = nums[nums.length - 1]; + + for (int i = nums.length - 2; i >= 0; --i) { + int curr = Math.max(maxOfOneStepAhead, maxOfTwoStepsAhead + nums[i]); + + maxOfTwoStepsAhead = maxOfOneStepAhead; + maxOfOneStepAhead = curr; + } + return maxOfOneStepAhead; + } +} diff --git a/longest-palindromic-substring/bky373.java b/longest-palindromic-substring/bky373.java new file mode 100644 index 000000000..59fdc64aa --- /dev/null +++ b/longest-palindromic-substring/bky373.java @@ -0,0 +1,104 @@ +class Solution { + + /* + * Approach 1. + * time: O(n^3) + * space: O(1) + */ + public String longestPalindrome1(String s) { + String longest = ""; + for (int i = 0; i < s.length(); i++) { + for (int j = i; j < s.length(); j++) { + String ss = s.substring(i, j + 1); + if (isPalindrome(ss)) { + if (ss.length() > longest.length()) { + longest = ss; + } + } + } + } + return longest; + } + + // Approach 1. + private boolean isPalindrome(String s) { + int left = 0; + int right = s.length() - 1; + while (left < right) { + if (s.charAt(left) != s.charAt(right)) { + return false; + } + left++; + right--; + } + return true; + } + + /* + * Approach 2-1. + * time: 시간 복잡도는 평균적으로 O(n)이고, palindrome 의 길이가 n 에 가까워지면 시간 복잡도 역시 O(n^2) 에 가까워 진다. + * space: O(1) + */ + class Solution { + + public String longestPalindrome(String s) { + int maxStart = 0; + int maxEnd = 0; + + for (int i = 0; i < s.length(); i++) { + int start = i; + int end = i; + while (0 <= start && end < s.length() && s.charAt(start) == s.charAt(end)) { + if (maxEnd - maxStart < end - start) { + maxStart = start; + maxEnd = end; + } + start--; + end++; + } + + start = i; + end = i + 1; + while (0 <= start && end < s.length() && s.charAt(start) == s.charAt(end)) { + if (maxEnd - maxStart < end - start) { + maxStart = start; + maxEnd = end; + } + start--; + end++; + } + } + return s.substring(maxStart, maxEnd + 1); + } + } + + /* + * Approach 2-2. + * time: 시간 복잡도는 평균적으로 O(n)이고, palindrome 의 길이가 n 에 가까워지면 시간 복잡도 역시 O(n^2) 에 가까워 진다. + * space: O(1) + */ + class Solution { + int maxStart = 0; + int maxEnd = 0; + + public String longestPalindrome(String s) { + for (int i = 0; i < s.length(); i++) { + calculateMaxLength(i, i, s); + calculateMaxLength(i, i+1, s); + } + return s.substring(maxStart, maxEnd + 1); + } + + public void calculateMaxLength(int start, int end, String s){ + while (start >= 0 && end < s.length() && s.charAt(start) == s.charAt(end)) { + if (this.maxEnd - this.maxStart < end - start) { + this.maxStart = start; + this.maxEnd = end; + } + start--; + end++; + } + } + + } +} diff --git a/number-of-connected-components-in-an-undirected-graph/bky373.java b/number-of-connected-components-in-an-undirected-graph/bky373.java new file mode 100644 index 000000000..9080a1295 --- /dev/null +++ b/number-of-connected-components-in-an-undirected-graph/bky373.java @@ -0,0 +1,42 @@ +/* + time: O(n+m), where n is the number of nodes and m is the number of edges in the graph. + space: O(n) + */ +class Solution { + + public int countComponents(int n, int[][] edges) { + boolean[] visited = new boolean[n]; + + Map> map = new HashMap<>(); + for (int[] edge : edges) { + map.computeIfAbsent(edge[0], k -> new ArrayList<>()) + .add(edge[1]); + map.computeIfAbsent(edge[1], k -> new ArrayList<>()) + .add(edge[0]); + } + + int ans = 0; + for (int i = 0; i < n; i++) { + if (visited[i]) { + continue; + } + dfs(i, map, visited); + ans++; + } + return ans; + } + + public void dfs(int k, Map> map, boolean[] visited) { + if (visited[k]) { + return; + } + visited[k] = true; + if (!map.containsKey(k)) { + return; + } + List values = map.get(k); + for (int v : values) { + dfs(v, map, visited); + } + } +}