-
-
Notifications
You must be signed in to change notification settings - Fork 10
/
148 Sort List.swift
137 lines (108 loc) · 3.08 KB
/
148 Sort List.swift
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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
//
// 148 Sort List.swift
// LeetCode-Solutions
//
// Created by Aleksandar Dinic on 13/10/2020.
// Copyright © 2020 Aleksandar Dinic. All rights reserved.
//
import Foundation
/// Source: https://leetcode.com/problems/sort-list/
class Solution {
private var tail = ListNode(-1)
private var nextSublist: ListNode? = ListNode(-1)
/// Sorts linked list in ascending order.
///
/// - Parameter head: Head of the linked list.
/// - Returns: Head of the linked list after sorting.
///
/// - Complexity:
/// - time: O(n log(n)), where n is the number of nodes in the linked list.
/// - space: O(1), only constant space is used.
func sortList(_ head: ListNode?) -> ListNode? {
guard head?.next != nil else { return head }
var start = head
let dummy = ListNode(-1)
var size = 1
let n = getCount(head)
while size < n {
tail = dummy
while start != nil {
guard start?.next != nil else {
tail.next = start
break
}
var mid = split(start, size)
merge(&start, &mid)
start = nextSublist
}
start = dummy.next
size *= 2
}
return dummy.next
}
private func split(_ start: ListNode?, _ size: Int) -> ListNode? {
var start = start
var end = start?.next
for _ in 1..<size {
if let endNext = end?.next {
end = endNext.next ?? endNext
}
if let startNext = start?.next {
start = startNext
}
}
let mid = start?.next
start?.next = nil
nextSublist = end?.next
end?.next = nil
return mid
}
private func merge(_ list1: inout ListNode?, _ list2: inout ListNode?) {
let dummy = ListNode(-1)
var newTail: ListNode? = dummy
while let list1Val = list1?.val, let list2Val = list2?.val {
if list1Val < list2Val {
newTail?.next = list1
list1 = list1?.next
} else {
newTail?.next = list2
list2 = list2?.next
}
newTail = newTail?.next
}
newTail?.next = list1 != nil ? list1 : list2
while newTail?.next != nil {
newTail = newTail?.next
}
tail.next = dummy.next
if let newTail = newTail {
tail = newTail
}
}
private func getCount(_ head: ListNode?) -> Int {
var count = 0
var cur = head
while cur != nil {
cur = cur?.next
count += 1
}
return count
}
}
/// Provided code
public class ListNode {
public var val: Int
public var next: ListNode?
public init() {
self.val = 0
self.next = nil
}
public init(_ val: Int) {
self.val = val
self.next = nil
}
public init(_ val: Int, _ next: ListNode?) {
self.val = val
self.next = next
}
}