diff --git a/3sum/kdh-92.java b/3sum/kdh-92.java new file mode 100644 index 000000000..f70934ba7 --- /dev/null +++ b/3sum/kdh-92.java @@ -0,0 +1,38 @@ +/** + * 특이사항 + * 문제를 제대로 이해 못해서 풀이를 보며 이해했다. + * 핵심은 중복 처리와 문제를 찾았을 때 종료가 아니라 다음 항목을 찾는 부분인 것 같다. + * (추후 복습 예정) + */ + +class Solution { + public List> threeSum(int[] nums) { + + // (1) ArrayList + // 시간복잡도 : O(N^2), 공간복잡도 : O(N) + List> result = new ArrayList<>(); + Arrays.sort(nums); + + for (int i = 0; i < nums.length; i++) { + if (i > 0 && nums[i] == nums[i - 1]) continue; + + int j = i + 1; + int k = nums.length - 1; + + while (j < k) { + int sumNum = nums[i] + nums[j] + nums[k]; + + if (sumNum > 0) k--; + else if (sumNum < 0) j++; + else { + result.add(Arrays.asList(nums[i], nums[j], nums[k])); + j++; + + while (nums[j] == nums[j - 1] && j < k) j++; + } + } + } + + return result; + } +} diff --git a/climbing-stairs/kdh-92.java b/climbing-stairs/kdh-92.java new file mode 100644 index 000000000..b6434c076 --- /dev/null +++ b/climbing-stairs/kdh-92.java @@ -0,0 +1,18 @@ +class Solution { + public int climbStairs(int n) { + // dp 응용 버전 + // 시간복잡도 : O(N), 공간복잡도 : O(1) + + int prev = 1, curr = 1; + + if (n == 1) return prev; + + for (int i = 2; i < n; i++) { + int now = curr + prev; + prev = curr; + curr = now; + } + + return curr; + } +} diff --git a/construct-binary-tree-from-preorder-and-inorder-traversal/kdh-92.java b/construct-binary-tree-from-preorder-and-inorder-traversal/kdh-92.java new file mode 100644 index 000000000..ce8c8a85f --- /dev/null +++ b/construct-binary-tree-from-preorder-and-inorder-traversal/kdh-92.java @@ -0,0 +1,36 @@ +/** + * 특이사항 + * TreeNode 이해 & right 설정 부분 이해 필요 + * - 재귀 호출 형태로 if 조건 추가 (preStart > preorder.length -1 || inStart > inEnd) 일 경우엔 null 반환 + * - null일 때 상황 테스트하며 좀 더 살펴보기 + * + * - right + * - preStart : preStart + inIdx - inStart + 1 (left 동일하게 preStart + 1에서 inIdx - inStart 를 추가해서 오른쪽 영역 탐색) + */ + +class Solution { + public static TreeNode buildTree(int[] preorder, int[] inorder) { + // (1) helper 메소드를 재귀호출 사용 + // 시간복잡도 : O(N^2), 공간복잡도 : O(N) + + return helper(0, 0, inorder.length - 1, preorder, inorder); + } + + public static TreeNode helper(int preStart, int inStart, int inEnd, int[] preorder, int[] inorder) { + if (preStart > preorder.length - 1 || inStart > inEnd) return null; + TreeNode node = new TreeNode(preorder[preStart]); + int inIdx = 0; + + for (int i = inStart; i <= inEnd; i++) { + if (node.val == inorder[i]) { + inIdx = i; + break; + } + } + + node.left = helper(preStart + 1, inStart, inIdx - 1, preorder, inorder); + node.right = helper(preStart + inIdx - inStart + 1, inIdx + 1, inEnd, preorder, inorder); + + return node; + } +} diff --git a/valid-anagram/kdh-92.java b/valid-anagram/kdh-92.java new file mode 100644 index 000000000..b37d17e43 --- /dev/null +++ b/valid-anagram/kdh-92.java @@ -0,0 +1,66 @@ +/** + * 특이사항 + * 시간복잡도가 (1)번 풀이는 O(N log N) / (2), (3)번 풀이는 O(N)인데 + * 리트코드에서 Runtime - (1)번 : 3ms, (3)번 : 6ms, (2)번 : 13ms + * + * 시간복잡도로만 따지면 당연히 (2), (3)번 풀이가 빨라야하는데도 불구하고 오히려 (1)번 풀이가 더 빠른 결과가 나온다. + * chatgpt 확인했을 때 가장 큰 차이점은 문자열을 배열로 변경해서 정렬을 하는데 이 때 정렬 알고리즘의 성능에 따라 차이가 난다는 내용이 있었다. + * N이 높아질수록 (2), (3)의 성능이 좋아질 것으로 예상되나 해당 문제의 결과에서는 (1)의 성능이 좋게 나올 수 있다는 것을 알게 되었다. + */ + +class Solution { + public boolean isAnagram(String s, String t) { + // (1) 문자 배열 - 정렬 & 비교 + // 시간복잡도 : O(N log N), 공간복잡도 : O(N) + + // char[] sArr = s.toCharArray(); + // char[] tArr = t.toCharArray(); + // Arrays.sort(sArr); + // Arrays.sort(tArr); + + // return new String(sArr).equals(new String(tArr)); // 문자열을 비교한다 생각했을 때 방법 + // return Arrays.equals(sArr, tArr); // char 배열 자체를 비교 + + // (2) HashMap 이용해 알파벳 개수 체크 + // 시간복잡도 : O(N), 공간복잡도 : O(N) + + // Map count = new HashMap<>(); + + // for (char x : s.toCharArray()) { + // count.put(x, count.getOrDefault(x, 0) + 1); + // } + + // for (char x : t.toCharArray()) { + // count.put(x, count.getOrDefault(x, 0) - 1); + // } + + // for (int val : count.values()) { + // if (val != 0) { + // return false; + // } + // } + + // return true; + + // (3) 배열로 알파벳 개수 체크 + // 시간복잡도 : O(N), 공간복잡도 : O(N) + + // if (s.length() != t.length()) { + // return false; + // } + + // int[] freq = new int[26]; + // for (int i = 0; i < s.length(); i++) { + // freq[s.charAt(i) - 'a']++; + // freq[t.charAt(i) - 'a']--; + // } + + // for (int i = 0; i < freq.length; i++) { + // if (freq[i] != 0) { + // return false; + // } + // } + + // return true; + } +}