Skip to content

Commit 61ca2b9

Browse files
committed
1834_Single_Threaded_CPU
1 parent 9e9ef4f commit 61ca2b9

File tree

2 files changed

+259
-0
lines changed

2 files changed

+259
-0
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -362,6 +362,7 @@ I have solved quite a number of problems from several topics. See the below tabl
362362
|17| **[846. Hand of Straights](https://tinyurl.com/y2hfqqsv)** | [Python](https://tinyurl.com/wu6rdaw/846_Hand_of_Straights.py)| **[Art 1](https://tinyurl.com/w8pkf55)** | Medium | 📌 TODO: Check again. Very important |
363363
|18| **[1167. Minimum Cost to Connect Sticks](https://tinyurl.com/y8s5s8pq)** | [Python](https://tinyurl.com/wu6rdaw/1167_Minimum_Cost_to_Connect_Sticks.py)| [Art 1](https://tinyurl.com/ycedphuh) | Medium | |
364364
|19| **[1102. Path With Maximum Minimum Value](https://tinyurl.com/y7zqxqpq)** | [Python](https://tinyurl.com/wu6rdaw/1102_Path_With_Maximum_Minimum_Value.py)| [Art 1](https://tinyurl.com/yb7p48lk), [Art 2](https://tinyurl.com/ya34o3z2), [Art 3](https://tinyurl.com/y99bhurp) | Medium | Dijekstra |
365+
|20| **[1834. Single-Threaded CPU](https://tinyurl.com/yk66fo4v)** | [Swift](https://tinyurl.com/wuja3c4/1834_Single_Threaded_CPU.swift) | [Art 1](https://tinyurl.com/yjbn9uzs) | Medium | --- |
365366

366367
</p>
367368
</details>
Lines changed: 258 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,258 @@
1+
class Solution {
2+
func getOrder(_ tasks: [[Int]]) -> [Int] {
3+
guard tasks.count > 1 else {
4+
return [0]
5+
}
6+
7+
var tasksSorted = [(Int, Int, Int)]() // (StartTime, ProcessingTime, OriginalTaskIndex)
8+
for (index, item) in tasks.enumerated() {
9+
tasksSorted.append((item[0], item[1], index))
10+
}
11+
tasksSorted = tasksSorted.sorted(by: { $0.0 == $1.0 ? ($0.1 == $1.1 ? $0.2 < $1.2 : $0.1 < $1.1) : $0.0 < $1.0 })
12+
13+
var result = [Int]()
14+
var minHeap = Heap<(Int, Int, Int)>(sort: {
15+
$0.1 == $1.1 ? $0.2 < $1.2 : $0.1 < $1.1
16+
})
17+
var (currentSortedTaskIndex, currentTime) = (0, tasksSorted.first!.0)
18+
while result.count < tasksSorted.count {
19+
while currentSortedTaskIndex < tasksSorted.count && tasksSorted[currentSortedTaskIndex].0 <= currentTime {
20+
minHeap.insert(tasksSorted[currentSortedTaskIndex])
21+
currentSortedTaskIndex += 1
22+
}
23+
24+
if !minHeap.isEmpty {
25+
let (_, processingTime, index) = minHeap.remove()!
26+
result.append(index)
27+
currentTime += processingTime
28+
} else if currentSortedTaskIndex < tasksSorted.count {
29+
currentTime = tasksSorted[currentSortedTaskIndex].0
30+
}
31+
}
32+
return result
33+
}
34+
}
35+
36+
37+
//SOURCE: https://github.com/raywenderlich/swift-algorithm-club/blob/master/Heap/Heap.swift
38+
//
39+
// Heap.swift
40+
// Written for the Swift Algorithm Club by Kevin Randrup and Matthijs Hollemans
41+
//
42+
public struct Heap<T> {
43+
44+
/** The array that stores the heap's nodes. */
45+
var nodes = [T]()
46+
47+
/**
48+
* Determines how to compare two nodes in the heap.
49+
* Use '>' for a max-heap or '<' for a min-heap,
50+
* or provide a comparing method if the heap is made
51+
* of custom elements, for example tuples.
52+
*/
53+
private var orderCriteria: (T, T) -> Bool
54+
55+
/**
56+
* Creates an empty heap.
57+
* The sort function determines whether this is a min-heap or max-heap.
58+
* For comparable data types, > makes a max-heap, < makes a min-heap.
59+
*/
60+
public init(sort: @escaping (T, T) -> Bool) {
61+
self.orderCriteria = sort
62+
}
63+
64+
/**
65+
* Creates a heap from an array. The order of the array does not matter;
66+
* the elements are inserted into the heap in the order determined by the
67+
* sort function. For comparable data types, '>' makes a max-heap,
68+
* '<' makes a min-heap.
69+
*/
70+
public init(array: [T], sort: @escaping (T, T) -> Bool) {
71+
self.orderCriteria = sort
72+
configureHeap(from: array)
73+
}
74+
75+
/**
76+
* Configures the max-heap or min-heap from an array, in a bottom-up manner.
77+
* Performance: This runs pretty much in O(n).
78+
*/
79+
private mutating func configureHeap(from array: [T]) {
80+
nodes = array
81+
for i in stride(from: (nodes.count/2-1), through: 0, by: -1) {
82+
shiftDown(i)
83+
}
84+
}
85+
86+
public var isEmpty: Bool {
87+
return nodes.isEmpty
88+
}
89+
90+
public var count: Int {
91+
return nodes.count
92+
}
93+
94+
/**
95+
* Returns the index of the parent of the element at index i.
96+
* The element at index 0 is the root of the tree and has no parent.
97+
*/
98+
@inline(__always) internal func parentIndex(ofIndex i: Int) -> Int {
99+
return (i - 1) / 2
100+
}
101+
102+
/**
103+
* Returns the index of the left child of the element at index i.
104+
* Note that this index can be greater than the heap size, in which case
105+
* there is no left child.
106+
*/
107+
@inline(__always) internal func leftChildIndex(ofIndex i: Int) -> Int {
108+
return 2*i + 1
109+
}
110+
111+
/**
112+
* Returns the index of the right child of the element at index i.
113+
* Note that this index can be greater than the heap size, in which case
114+
* there is no right child.
115+
*/
116+
@inline(__always) internal func rightChildIndex(ofIndex i: Int) -> Int {
117+
return 2*i + 2
118+
}
119+
120+
/**
121+
* Returns the maximum value in the heap (for a max-heap) or the minimum
122+
* value (for a min-heap).
123+
*/
124+
public func peek() -> T? {
125+
return nodes.first
126+
}
127+
128+
/**
129+
* Adds a new value to the heap. This reorders the heap so that the max-heap
130+
* or min-heap property still holds. Performance: O(log n).
131+
*/
132+
public mutating func insert(_ value: T) {
133+
nodes.append(value)
134+
shiftUp(nodes.count - 1)
135+
}
136+
137+
/**
138+
* Adds a sequence of values to the heap. This reorders the heap so that
139+
* the max-heap or min-heap property still holds. Performance: O(log n).
140+
*/
141+
public mutating func insert<S: Sequence>(_ sequence: S) where S.Iterator.Element == T {
142+
for value in sequence {
143+
insert(value)
144+
}
145+
}
146+
147+
/**
148+
* Allows you to change an element. This reorders the heap so that
149+
* the max-heap or min-heap property still holds.
150+
*/
151+
public mutating func replace(index i: Int, value: T) {
152+
guard i < nodes.count else { return }
153+
154+
remove(at: i)
155+
insert(value)
156+
}
157+
158+
/**
159+
* Removes the root node from the heap. For a max-heap, this is the maximum
160+
* value; for a min-heap it is the minimum value. Performance: O(log n).
161+
*/
162+
@discardableResult public mutating func remove() -> T? {
163+
guard !nodes.isEmpty else { return nil }
164+
165+
if nodes.count == 1 {
166+
return nodes.removeLast()
167+
} else {
168+
// Use the last node to replace the first one, then fix the heap by
169+
// shifting this new first node into its proper position.
170+
let value = nodes[0]
171+
nodes[0] = nodes.removeLast()
172+
shiftDown(0)
173+
return value
174+
}
175+
}
176+
177+
/**
178+
* Removes an arbitrary node from the heap. Performance: O(log n).
179+
* Note that you need to know the node's index.
180+
*/
181+
@discardableResult public mutating func remove(at index: Int) -> T? {
182+
guard index < nodes.count else { return nil }
183+
184+
let size = nodes.count - 1
185+
if index != size {
186+
nodes.swapAt(index, size)
187+
shiftDown(from: index, until: size)
188+
shiftUp(index)
189+
}
190+
return nodes.removeLast()
191+
}
192+
193+
/**
194+
* Takes a child node and looks at its parents; if a parent is not larger
195+
* (max-heap) or not smaller (min-heap) than the child, we exchange them.
196+
*/
197+
internal mutating func shiftUp(_ index: Int) {
198+
var childIndex = index
199+
let child = nodes[childIndex]
200+
var parentIndex = self.parentIndex(ofIndex: childIndex)
201+
202+
while childIndex > 0 && orderCriteria(child, nodes[parentIndex]) {
203+
nodes[childIndex] = nodes[parentIndex]
204+
childIndex = parentIndex
205+
parentIndex = self.parentIndex(ofIndex: childIndex)
206+
}
207+
208+
nodes[childIndex] = child
209+
}
210+
211+
/**
212+
* Looks at a parent node and makes sure it is still larger (max-heap) or
213+
* smaller (min-heap) than its childeren.
214+
*/
215+
internal mutating func shiftDown(from index: Int, until endIndex: Int) {
216+
let leftChildIndex = self.leftChildIndex(ofIndex: index)
217+
let rightChildIndex = leftChildIndex + 1
218+
219+
// Figure out which comes first if we order them by the sort function:
220+
// the parent, the left child, or the right child. If the parent comes
221+
// first, we're done. If not, that element is out-of-place and we make
222+
// it "float down" the tree until the heap property is restored.
223+
var first = index
224+
if leftChildIndex < endIndex && orderCriteria(nodes[leftChildIndex], nodes[first]) {
225+
first = leftChildIndex
226+
}
227+
if rightChildIndex < endIndex && orderCriteria(nodes[rightChildIndex], nodes[first]) {
228+
first = rightChildIndex
229+
}
230+
if first == index { return }
231+
232+
nodes.swapAt(index, first)
233+
shiftDown(from: first, until: endIndex)
234+
}
235+
236+
internal mutating func shiftDown(_ index: Int) {
237+
shiftDown(from: index, until: nodes.count)
238+
}
239+
240+
}
241+
242+
// MARK: - Searching
243+
extension Heap where T: Equatable {
244+
245+
/** Get the index of a node in the heap. Performance: O(n). */
246+
public func index(of node: T) -> Int? {
247+
return nodes.index(where: { $0 == node })
248+
}
249+
250+
/** Removes the first occurrence of a node from the heap. Performance: O(n). */
251+
@discardableResult public mutating func remove(node: T) -> T? {
252+
if let index = index(of: node) {
253+
return remove(at: index)
254+
}
255+
return nil
256+
}
257+
258+
}

0 commit comments

Comments
 (0)