|
| 1 | +--- |
| 2 | +layout: post |
| 3 | +title: (Leetcode) 143 - Reorder List |
| 4 | +categories: [스터디-알고리즘] |
| 5 | +tags: |
| 6 | + [ |
| 7 | + 자바, |
| 8 | + java, |
| 9 | + 리트코드, |
| 10 | + Leetcode, |
| 11 | + 알고리즘, |
| 12 | + algorithm, |
| 13 | + array, |
| 14 | + list, |
| 15 | + pointer, |
| 16 | + linked list, |
| 17 | + ] |
| 18 | +date: 2024-06-10 01:00:00 +0900 |
| 19 | +toc: true |
| 20 | +--- |
| 21 | + |
| 22 | +기회가 되어 [달레님의 스터디](https://github.com/DaleStudy/leetcode-study)에 참여하여 시간이 될 때마다 한문제씩 풀어보고 있다. |
| 23 | + |
| 24 | +[https://neetcode.io/practice](https://neetcode.io/practice) |
| 25 | + |
| 26 | +--- |
| 27 | + |
| 28 | +[https://leetcode.com/problems/reorder-list/](https://leetcode.com/problems/reorder-list/) |
| 29 | + |
| 30 | +## 내가 작성한 풀이 |
| 31 | + |
| 32 | +두 가지 방법으로 풀어봤다. |
| 33 | + |
| 34 | +### list 로 풀기 |
| 35 | + |
| 36 | +```java |
| 37 | +class Solution { |
| 38 | + public boolean isValidBST(TreeNode root) { |
| 39 | + return dfs(root.left, (long) Integer.MIN_VALUE - 1, root.val) |
| 40 | + && dfs(root.right, root.val, (long) Integer.MAX_VALUE + 1); |
| 41 | + } |
| 42 | + |
| 43 | + private boolean dfs(TreeNode node, long min, long max) { |
| 44 | + if (node == null) { |
| 45 | + return true; |
| 46 | + } |
| 47 | + |
| 48 | + // left로 갈 때 max를 자신으로, right로 갈 때는 min을 자신으로 |
| 49 | + if (!(dfs(node.left, min, node.val) |
| 50 | + && dfs(node.right, node.val, max))) { |
| 51 | + return false; |
| 52 | + } |
| 53 | + |
| 54 | + return node.val > min && node.val < max; |
| 55 | + } |
| 56 | +} |
| 57 | +``` |
| 58 | + |
| 59 | +#### TC, SC |
| 60 | + |
| 61 | +시간 복잡도는 O(n)이고, 공간 복잡도는 O(n)이다. |
| 62 | + |
| 63 | +### pointer 로 풀기 |
| 64 | + |
| 65 | +포인터로도 풀 수 있을 것 같아서 찾아보았더니 방법이 있는것 같길래 참고하여 코드를 작성해보았다. |
| 66 | +slow와 fast를 이용하여 뒤집을 부분과 유지할 부분을 나누는 것이 재밌는 접근이였던것 같다. |
| 67 | + |
| 68 | +```java |
| 69 | +class Solution { |
| 70 | + public void reorderList(ListNode head) { |
| 71 | + ListNode prev = null; |
| 72 | + ListNode slow = head; |
| 73 | + ListNode fast = head; |
| 74 | + |
| 75 | + while(slow != null && fast != null && fast.next != null) { |
| 76 | + prev = slow; |
| 77 | + slow = slow.next; |
| 78 | + fast = fast.next.next; |
| 79 | + } |
| 80 | + |
| 81 | + if (prev == null) { |
| 82 | + return; |
| 83 | + } |
| 84 | + |
| 85 | + prev.next = null; |
| 86 | + |
| 87 | + ListNode current = head; |
| 88 | + ListNode reversed = reverse(slow); |
| 89 | + while(true) { |
| 90 | + ListNode temp = current.next; |
| 91 | + |
| 92 | + if (reversed != null) { |
| 93 | + current.next = reversed; |
| 94 | + reversed = reversed.next; |
| 95 | + current = current.next; |
| 96 | + } |
| 97 | + |
| 98 | + if (temp != null) { |
| 99 | + current.next = temp; |
| 100 | + current = current.next; |
| 101 | + } else { |
| 102 | + current.next = reversed; |
| 103 | + break; |
| 104 | + } |
| 105 | + } |
| 106 | + } |
| 107 | + |
| 108 | + public ListNode reverse(ListNode treeNode) { |
| 109 | + ListNode current = treeNode; |
| 110 | + ListNode prev = null; |
| 111 | + while(current != null) { |
| 112 | + ListNode temp = current.next; |
| 113 | + current.next = prev; |
| 114 | + prev = current; |
| 115 | + current = temp; |
| 116 | + } |
| 117 | + return prev; |
| 118 | + } |
| 119 | +} |
| 120 | +``` |
| 121 | + |
| 122 | +#### TC, SC |
| 123 | + |
| 124 | +시간 복잡도는 O(n)이고, 공간 복잡도는 O(1)이다. |
| 125 | + |
| 126 | +## 마무리 |
| 127 | + |
| 128 | +두번째 풀이가 공간 복잡도가 줄었으나 다만 실제로 수행된 결과를 비교해보면 시간과 공간 측면에서 큰 차이는 없었다. 오히려 늘어난 면이 있다. 코드도 많이 복잡해졌다고 생각한다. |
| 129 | + |
| 130 | +| 방식 | 실행 시간 | 메모리 | |
| 131 | +| ------- | --------- | ------- | |
| 132 | +| list | 3 ms | 47.6 MB | |
| 133 | +| pointer | 2 ms | 48.2 MB | |
| 134 | + |
| 135 | +물론 input 케이스에 따라 달라질 수 있을 것이다. |
| 136 | + |
| 137 | +일단은 어떻게 접근할지 여러가지 방법으로 고민하는 것에 의의를 둬야 할 것 같다. |
0 commit comments