728x90
반응형
Sort List
Given the head of a linked list, return the list after sorting it in ascending order.
Example 1:
Input: head = [4,2,1,3]
Output: [1,2,3,4]
Example 2:
Input: head = [-1,5,3,4,0]
Output: [-1,0,3,4,5]
Example 3:
Input: head = []
Output: []
Constraints:
- The number of nodes in the list is in the range [0, 5 * 104].
- -105 <= Node.val <= 105
Follow up:
Can you sort the linked list in O(n logn) time and O(1) memory (i.e. constant space)?
풀이 - 1
ListNode class에 대한 이해가 너무 되지않아 엄청 헤멨다.. 결국 메모리 참조값을 바꿔버리는 방식으로 구현해보았다.
class ListNode {
val: number;
next: ListNode | null;
constructor(val?: number, next?: ListNode | null) {
this.val = val === undefined ? 0 : val;
this.next = next === undefined ? null : next;
}
}
function swapNode(head: ListNode, count: number): boolean {
for (let i = 0; i < count; i++) {
head = head.next!;
}
if (head.val > head.next!.val) {
[head.val, head.next!.val] = [head.next!.val, head.val];
return true;
}
return false;
}
function isNull(head: ListNode, count: number): boolean {
for (let i = 0; i < count; i++) {
head = head.next!;
}
return !!head.next;
}
function sortList(head: ListNode | null): ListNode | null {
if (!head || !head.val || !head.next) {
return head;
}
let isConvert: boolean = false;
let count: number = 0;
while (isNull(head, count)) {
isConvert = swapNode(head, count);
count++;
}
if (isConvert) {
return sortList(head);
}
return head;
}
버블정렬이 생각나서 재귀함수와 while문을 활용하기위해 isConvert로 정렬 여부를 확인하고 count로 next가 비어있을때까지만 확인하는 방식을 적용해보았지만 head = [-1,5,3,4,0]의 케이스에서 [-1,0,3,4,5]가 나와야하는데 [-1,3,0,4,5]가 나오게되어 실패하였다.
풀이 - 2
뭔가 while문이 다 돌기전, 혹은 isConvert가 true조건이 될때인데 그전에 return되어버리는건 아닐까 싶어 if 문을 while문 안에 넣어보았다.
function swapNode(head: ListNode, count: number): boolean {
for (let i = 0; i < count; i++) {
head = head.next!;
}
if (head.val > head.next!.val) {
[head.val, head.next!.val] = [head.next!.val, head.val];
return true;
}
return false;
}
function isNull(head: ListNode, count: number): boolean {
for (let i = 0; i < count; i++) {
head = head.next!;
}
return !!head.next;
}
function sortList(head: ListNode | null): ListNode | null {
if (!head || !head.val || !head.next) {
return head;
}
let isConvert: boolean = false;
let count: number = 0;
while (isNull(head, count)) {
isConvert = swapNode(head, count);
if (isConvert) {
return sortList(head);
}
count++;
}
return head;
}
최적화만 하면 풀릴것 같다 !
풀이 - 3
세션 안들은 티가 났던거 같다.. merge sort와 재귀함수를 응용하니 단번에 풀리게 되었다.
class ListNode {
val: number;
next: ListNode | null;
constructor(val?: number, next?: ListNode | null) {
this.val = val === undefined ? 0 : val;
this.next = next === undefined ? null : next;
}
}
function merge(left: ListNode | null, right: ListNode | null): ListNode | null {
if (!left) {
return right;
}
if (!right) {
return left;
}
if (left.val < right.val) {
left.next = merge(left.next, right);
return left;
} else {
right.next = merge(left, right.next);
return right;
}
}
function sortList(head: ListNode | null): ListNode | null {
if (!head || !head.next) {
return head;
}
let slow: ListNode | null = head;
let fast: ListNode | null = head;
let prev: ListNode | null = null;
while (fast && fast.next) {
prev = slow;
slow = slow!.next;
fast = fast!.next!.next;
}
prev!.next = null;
const left: ListNode | null = sortList(head);
const right: ListNode | null = sortList(slow);
return merge(left, right);
}
728x90
반응형
'개발일지 > TIL' 카테고리의 다른 글
[Hash Table 구현] Linear Probing 방식의 Hash Table을 구현해 보세요. (0) | 2023.09.04 |
---|---|
[leetcode] 219. Contains Duplicate II (0) | 2023.08.31 |
[leetcode] 1. Two Sum (0) | 2023.08.31 |
[leetcode] 150. Evaluate Reverse Polish Notation (0) | 2023.08.31 |
[leetcode] 155. Min Stack (0) | 2023.08.31 |