일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 | 31 |
- CPP
- graph
- 메모이제이션
- binary
- 탐욕알고리즘
- C++
- Greedy
- dynamic programming
- unordered_map
- 이진탐색
- binary search
- DFS
- algorithm
- 알고리즘
- Array
- 동적계획법
- Interval
- union-find
- 비트 조작
- 깊이 우선 탐색
- LeetCode
- bit manipulation
- linked list
- Sorting
- 비트 연산
- Depth-First Search
- 배열
- bitwise operation
- Sort
- hash table
- Today
- Total
공대생 공부노트(Notes for Engineering Studies)
[ leetcode 문제풀이 ] Reorder List 본문
[ leetcode 문제풀이 ] Reorder List
301동 노숙자 2022. 3. 5. 17:06https://leetcode.com/problems/reorder-list/
Reorder List - LeetCode
Level up your coding skills and quickly land a job. This is the best place to expand your knowledge and get prepared for your next interview.
leetcode.com
(Reorder List 문제는 위 링크에서 풀어보실 수 있습니다.)
< Reorder List 문제 설명 >
Reorder List 문제는 다음과 같다.
You are given the head of a singly linked-list. The list can be represented as:
L0 → L1 → … → Ln - 1 → Ln
Reorder the list to be on the following form:
L0 → Ln → L1 → Ln - 1 → L2 → Ln - 2 → …
You may not modify the values in the list's nodes. Only nodes themselves may be changed.
singly linked-list가 주어질 때(L0 → L1 → … → Ln - 1 → Ln) 순서를 재정렬해 L0 → Ln → L1 → Ln - 1 → L2 → Ln - 2 → … 와 같은 형태가 되도록 하여라. list 노드의 값은 변화시킬 수 없고, 오직 노드 자체만 변경할 수 있다.
다음 두 가지 출력 예시가 주어졌다.
주어진 제한조건은 다음과 같다:
list 노드의 수는 [1, 5*10^4] 범위 내에 있다.
1 ≤ Node.val ≤ 1000
< Reorder List 문제 접근(1) >
먼저 related topics에 있는 stack data structure을 이용해 알고리즘을 구현해보자.
stack에 ListNode를 순서대로 쌓은 후 전체 노드 중 뒤에서 절반에 해당하는 노드를 기존 list 중간중간에 삽입하면 될 것이다. (ex:1 → 2 → 3 → ... → n 이 있다고 할 때 stack에 ListNode를 저장하면 stack의 top은 n임. 이를 list 중간에 삽입한다.
1 → n → 2 → 3 → ... / now stack.top == n-1)
작성한 코드는 다음과 같다. (Cpp 사용)
#include <stack>
void reorderList(ListNode* head) {
if(!(head->next)) return;
ListNode* pointNode = head->next;
stack<ListNode*> NodeStack;
while(pointNode){
NodeStack.push(pointNode);
pointNode = pointNode->next;
}
pointNode = head;
while(pointNode != pointNode->next && pointNode != NodeStack.top()){
ListNode* elem = NodeStack.top();
NodeStack.pop();
elem->next = pointNode->next;
pointNode->next = elem;
pointNode = elem->next;
}
pointNode->next = nullptr;
} // runtime : 54 ms (faster than 59.95 %), memory usage : 18.6 MB (less than 23.60 %)
// algorithm using stack
< Reorder List 문제 접근(2) >
stack을 사용해서 작성하고 나니 굳이 stack을 써야하나? 생각이 들었다. ListNode의 앞뒤에서 노드를 찾아서 연결하면 되는 것이므로 이번에는 deque(double-ended queue)를 사용해보았다. deque에 ListNode를 모두 저장해두고, connectNode라는 함수를 재귀적으로 호출해 deque set의 앞, 뒤에서 번갈아가며 ListNode를 연결하였다.
작성한 코드는 다음과 같다. (Cpp 사용)
#include <deque>
void connectNode(ListNode* pointNode, deque<ListNode*>& NodeSet, bool popFront){
if(NodeSet.empty()){
pointNode->next = nullptr;
return;
}
ListNode* elem;
if(popFront){
elem = NodeSet.front();
NodeSet.pop_front();
pointNode->next = elem;
}
else{
elem = NodeSet.back();
NodeSet.pop_back();
pointNode->next = elem;
}
connectNode(elem, NodeSet, !popFront
}
void reorderList(ListNode* head) {
if(!(head->next)) return;
ListNode* pointNode = head->next;
deque<ListNode*> NodeSet;
while(pointNode){
NodeSet.push_back(pointNode);
pointNode = pointNode->next;
}
pointNode = head;
connectNode(pointNode, NodeSet, false);
} // runtime : 56 ms (faster than 56.42 %), memory usage : 18.6 MB (less than 23.60 %)
// algorithm using deque
stack과 deque를 사용해 두 가지 방법으로 알고리즘을 작성해보았는데, 본질적으로 n개의 노드가 있다고 할 때 n개의 연결관계를 수정해야 하기에 runtime / memory usage 측면에서 동일한 성능을 나타낸 것으로 보인다.
'2022 Algorithm Study(by leetcode) > Linked List' 카테고리의 다른 글
[ leetcode 문제풀이 ] Reverse Linked List (0) | 2022.03.04 |
---|---|
[ leetcode 문제풀이 ] Remove Nth Node From End of List (0) | 2022.03.04 |
[ leetcode 문제풀이 ] Merge K Sorted Lists (0) | 2022.03.04 |
[ leetcode 문제풀이 ] Merge Two Sorted Lists (0) | 2022.03.04 |
[ leetcode 문제풀이 ] Linked List Cycle (0) | 2022.03.04 |