[Swift]LeetCode767. 重构字符串 | Reorganize String

Given a string S, check if the letters can be rearranged so that two characters that are adjacent to each other are not the same.

If possible, output any possible result.  If not possible, return the empty string.

Example 1:

Input: S = "aab"
Output: "aba"

Example 2:

Input: S = "aaab"
Output: ""

Note:

  • S will consist of lowercase letters and have length in range [1, 500].

给定一个字符串S,检查是否能重新排布其中的字母,使得两相邻的字符不同。

若可行,输出任意可行的结果。若不可行,返回空字符串。

示例 1:

输入: S = "aab"
输出: "aba"

示例 2:

输入: S = "aaab"
输出: ""

注意:

  • S 只包含小写字母并且长度在[1, 500]区间内。

Runtime: 12 ms
Memory Usage: 20.2 MB
 1 class Solution {
 2     func reorganizeString(_ S: String) -> String {
 3         var n:Int = S.count
 4         var idx:Int = 1
 5         var cnt:[Int] = [Int](repeating:0,count:26)
 6         var arrChar:[Character] = Array(S)
 7         for char in S.characters
 8         {
 9             cnt[char.ascii - 97] += 100
10         }
11         for i in 0..<26
12         {
13             cnt[i] += i
14         }
15         cnt.sort()
16         for num in cnt
17         {
18             var t:Int = num / 100
19             var ch:Character = (97 + (num % 100)).ASCII
20             if t > (n + 1) / 2 {return String()}
21             for i in 0..<t
22             {
23                 if idx >= n {idx = 0}
24                 arrChar[idx] = ch
25                 idx += 2
26             }            
27         }
28         return String(arrChar)
29     }
30 }
31 
32 //Character扩展 
33 extension Character  
34 {  
35   //Character转ASCII整数值(定义小写为整数值)
36    var ascii: Int {
37        get {
38            return Int(self.unicodeScalars.first?.value ?? 0)
39        }       
40     }    
41 }
42 
43 //Int扩展
44 extension Int
45 {
46     //Int转Character,ASCII值(定义大写为字符值)
47     var ASCII:Character 
48     {
49         get {return Character(UnicodeScalar(self)!)}
50     }
51 }

12ms

 1 class Solution {
 2     func reorganizeString(_ s: String) -> String {
 3       let n = s.count
 4       var counts = [Int](repeating: 0, count: 26)
 5       for character in s {
 6         let index: Int = Int(character.unicodeScalars.first!.value - "a".unicodeScalars.first!.value)
 7         counts[index] += 100
 8       }
 9       for i in 0..<counts.count {
10         counts[i] += i
11       }
12       counts = counts.sorted(by: >)
13 
14       var output = [Character](repeating: " ", count:n)
15       var j = 0
16       for code in counts {
17         let count = code / 100
18         let charValue = Int("a".unicodeScalars.first!.value) + (code % 100)
19         let unicode = UnicodeScalar(charValue)!
20         let char = Character(unicode)
21         guard count <= (n + 1) / 2 else {
22           return ""
23         }
24 
25         for i in 0..<count {
26           if (j >= n) {
27             j = 1
28           }
29           output[j] = char
30           j += 2
31         }
32       }
33 
34       return String(output)
35     }
36 }

16ms

 1 class Solution {
 2     func reorganizeString(_ S: String) -> String {
 3         var s = Array(S.utf8)
 4         var counts = [Int](repeating: 0, count: 26)
 5         for u in s {
 6             counts[Int(u) - 97] += 1
 7         }
 8         var res = [Character]()
 9         var lastIndex = -1
10         while res.count != s.count {
11             guard let index = maxIndex(counts, lastIndex) else { 
12                 return "" 
13             }
14             counts[index] -= 1
15             lastIndex = index
16             res.append(Character(UnicodeScalar(index + 97)!))
17         }
18         return String(res)
19     }
20     
21     private func maxIndex(_ counts: [Int], _ notIndex: Int) -> Int? {
22         var maxC = 0
23         var retVal = -1
24         for i in 0..<26 {
25             if i != notIndex && counts[i] > maxC {
26                 retVal = i
27                 maxC = counts[i]
28             }   
29         }
30         return retVal == -1 ? nil : retVal
31     }
32 }

24ms

  1 class Solution {
  2     func reorganizeString(_ string: String) -> String {
  3         
  4         // we only care about the character counts, and not how the string is constructed
  5         let characterToCount = string.reduce(into: [:], { $0[$1, default: 0] += 1 })
  6         
  7         var maxHeap = Heap<(character: Character, count: Int)>(
  8             array: characterToCount.map { $0 },
  9             sort: { $0.count > $1.count })
 10         
 11         var newString = ""
 12         
 13         while let maxPair = maxHeap.remove() {
 14             
 15             // we can use the maxPair `character`
 16             if newString.last != maxPair.character {
 17                 
 18                 newString.append(maxPair.character)
 19                 
 20                 if maxPair.count > 1 {
 21                     maxHeap.insert((maxPair.character, maxPair.count-1))
 22                 }
 23             } else if let nextMaxPair = maxHeap.remove() {
 24                 
 25                 newString.append(nextMaxPair.character)
 26                 
 27                 if nextMaxPair.count > 1 {
 28                     maxHeap.insert((nextMaxPair.character, nextMaxPair.count-1))
 29                 }
 30                 maxHeap.insert(maxPair)
 31             } else {
 32                 return "" // we can't find any character to place in next
 33             }
 34         }
 35         
 36         return newString
 37     }
 38 }
 39 
 40 public struct Heap<T> {
 41     var elements = [T]()
 42     fileprivate var isOrderedBefore: (T, T) -> Bool
 43     public init(sort: @escaping (T, T) -> Bool) {
 44         self.isOrderedBefore = sort
 45     }
 46     public init(array: [T], sort: @escaping (T, T) -> Bool) {
 47         self.isOrderedBefore = sort
 48         buildHeap(fromArray: array)
 49     }
 50     fileprivate mutating func buildHeap(fromArray array: [T]) {
 51         elements = array
 52         for i in stride(from: (elements.count/2 - 1), through: 0, by: -1) {
 53             shiftDown(i, heapSize: elements.count)
 54         }
 55     }
 56     public var isEmpty: Bool {
 57         return elements.isEmpty
 58     }
 59 
 60     public var count: Int {
 61         return elements.count
 62     }
 63     @inline(__always) func parentIndex(ofIndex i: Int) -> Int {
 64         return (i - 1) / 2
 65     }
 66     @inline(__always) func leftChildIndex(ofIndex i: Int) -> Int {
 67         return 2*i + 1
 68     }
 69     @inline(__always) func rightChildIndex(ofIndex i: Int) -> Int {
 70         return 2*i + 2
 71     }
 72     public func peek() -> T? {
 73         return elements.first
 74     }
 75     public mutating func insert(_ value: T) {
 76         elements.append(value)
 77         shiftUp(elements.count - 1)
 78     }
 79     public mutating func insert<S: Sequence>(_ sequence: S) where S.Iterator.Element == T {
 80         for value in sequence {
 81             insert(value)
 82         }
 83     }
 84     public mutating func replace(index i: Int, value: T) {
 85         guard i < elements.count else { return }
 86 
 87         assert(isOrderedBefore(value, elements[i]))
 88         elements[i] = value
 89         shiftUp(i)
 90     }
 91     @discardableResult public mutating func remove() -> T? {
 92         if elements.isEmpty {
 93             return nil
 94         } else if elements.count == 1 {
 95             return elements.removeLast()
 96         } else {
 97             // Use the last node to replace the first one, then fix the heap by
 98             // shifting this new first node into its proper position.
 99             let value = elements[0]
100             elements[0] = elements.removeLast()
101             shiftDown()
102             return value
103         }
104     }
105     public mutating func removeAt(_ index: Int) -> T? {
106         guard index < elements.count else { return nil }
107 
108         let size = elements.count - 1
109         if index != size {
110             elements.swapAt(index, size)
111             // swap(&elements[index], &elements[size])
112             shiftDown(index, heapSize: size)
113             shiftUp(index)
114         }
115         return elements.removeLast()
116     }
117     mutating func shiftUp(_ index: Int) {
118         var childIndex = index
119         let child = elements[childIndex]
120         var parentIndex = self.parentIndex(ofIndex: childIndex)
121 
122         while childIndex > 0 && isOrderedBefore(child, elements[parentIndex]) {
123             elements[childIndex] = elements[parentIndex]
124             childIndex = parentIndex
125             parentIndex = self.parentIndex(ofIndex: childIndex)
126         }
127 
128         elements[childIndex] = child
129     }
130     mutating func shiftDown() {
131         shiftDown(0, heapSize: elements.count)
132     }
133     mutating func shiftDown(_ index: Int, heapSize: Int) {
134         var parentIndex = index
135 
136         while true {
137             let leftChildIndex = self.leftChildIndex(ofIndex: parentIndex)
138             let rightChildIndex = leftChildIndex + 1
139             var first = parentIndex
140             if leftChildIndex < heapSize && isOrderedBefore(elements[leftChildIndex], elements[first]) {
141                 first = leftChildIndex
142             }
143             if rightChildIndex < heapSize && isOrderedBefore(elements[rightChildIndex], elements[first]) {
144                 first = rightChildIndex
145             }
146             if first == parentIndex { return }
147 
148             elements.swapAt(parentIndex, first)
149             // swap(&elements[parentIndex], &elements[first])
150             parentIndex = first
151         }
152     }
153 }
154 extension Heap where T: Equatable {
155     public func index(of element: T) -> Int? {
156         return index(of: element, 0)
157     }
158     fileprivate func index(of element: T, _ i: Int) -> Int? {
159         if i >= count { return nil }
160         if isOrderedBefore(element, elements[i]) { return nil }
161         if element == elements[i] { return i }
162         if let j = index(of: element, self.leftChildIndex(ofIndex: i)) { return j }
163         if let j = index(of: element, self.rightChildIndex(ofIndex: i)) { return j }
164         return nil
165     }
166 }

36ms

  1 class Solution {
  2     func reorganizeString(_ S: String) -> String {
  3         var mapy = [Character: Int]()
  4         for c in S {
  5             mapy[c, default: 0] += 1
  6         }
  7         let heap = Heap<(Character, Int)>(elements: mapy.map { ($0.0,$0.1) }, priority: {
  8             return $0.1 > $1.1  
  9         })
 10         var arr = [Character]()
 11         while heap.isEmpty == false {
 12             var top = heap.dequeue()!
 13             if arr.last == top.0 {
 14                 if var second = heap.dequeue() {
 15                     arr.append(second.0)
 16                     second.1 -= 1
 17                     if top.1 > 0 {
 18                         heap.enqueue(top)
 19                     }
 20                     if second.1 > 0 {
 21                         heap.enqueue(second)
 22                     }
 23                 } else {
 24                     return ""
 25                 }
 26             } else {
 27                 arr.append(top.0)
 28                 top.1 -= 1
 29                 if top.1 > 0 {
 30                     heap.enqueue(top)
 31                 }
 32             }
 33         }
 34         return String(arr)
 35     }
 36 }
 37 
 38 final class Heap<T> {
 39 
 40     typealias Comparator = (T,T) -> Bool
 41 
 42     var elements: [T]
 43     let priority: Comparator
 44 
 45     init(elements: [T], priority: @escaping Comparator) {
 46         self.priority = priority
 47         self.elements = elements
 48         if elements.isEmpty == false {
 49             for i in stride(from: (count / 2) - 1, to: -1, by: -1) {
 50                 siftDown(i)
 51             }
 52         }
 53     }
 54 
 55     var isEmpty: Bool {
 56         return elements.isEmpty
 57     }
 58 
 59     var count: Int {
 60         return elements.count
 61     }
 62 
 63     var first: T? {
 64         return elements.first
 65     }
 66 
 67     func leftChildIndex(of index: Int) -> Int {
 68         return (2 * index) + 1
 69     }
 70 
 71     func rightChild(of index: Int) -> Int {
 72         return (2 * index) + 2
 73     }
 74 
 75     func parentIndex(of index: Int) -> Int {
 76         return (index - 1) / 2
 77     }
 78 
 79     func isHigherPriority(_ a: Int, _ b: Int) -> Bool {
 80         return priority(elements[a], elements[b])
 81     }
 82 
 83     func highestPriorityIndex(of index: Int) -> Int {
 84         let left = highestPriorityIndex(of: index, and: leftChildIndex(of: index))
 85         let right = highestPriorityIndex(of: index, and: rightChild(of: index))
 86         return highestPriorityIndex(of: left, and: right)
 87     }
 88 
 89     func highestPriorityIndex(of parent: Int, and child: Int) -> Int {
 90         guard child < count else {
 91             return parent
 92         }
 93         guard isHigherPriority(child, parent) else {
 94             return parent
 95         }
 96         return child
 97     }
 98 
 99     func enqueue(_ element: T) {
100         elements.append(element)
101         siftUp(count - 1)
102     }
103 
104     func siftUp(_ i: Int) {
105         let parent = parentIndex(of: i)
106         guard parent >= 0 else {
107             return
108         }
109         guard isHigherPriority(i, parent) else {
110             return
111         }
112         swap(i, parent)
113         siftUp(parent)
114     }
115 
116     func dequeue() -> T? {
117         guard count > 0 else {
118             return nil
119         }
120         return remove(at: 0)
121     }
122 
123     func remove(at i: Int) -> T? {
124         swap(i, count - 1)
125         let element = elements.popLast()
126         siftDown(i)
127         return element
128     }
129 
130     fileprivate func swap(_ i: Int, _ j: Int) {
131         (elements[i], elements[j]) = (elements[j], elements[i])
132     }
133 
134     func siftDown(_ i: Int) {
135         let indexToSwap = highestPriorityIndex(of: i)
136         guard indexToSwap != i else {
137             return
138         }
139         swap(indexToSwap, i)
140         siftDown(indexToSwap)
141     }
142 }

40ms

 1 class Solution {
 2     func reorganizeString(_ S: String) -> String {
 3         var countByChar = [Character:Int]()
 4         for c in Array(S) {
 5             countByChar[c, default:0] += 1
 6         }
 7         var chars = countByChar.keys.sorted { 
 8             return countByChar[$0]! > countByChar[$1]!
 9         }
10         var t = 0
11         var result = Array(repeating: Character("~"), count: S.count)
12         for c in chars {
13             for _ in 0..<countByChar[c]! {
14                 if countByChar[c]! > (S.count + 1) / 2 {
15                     return ""
16                 }
17                 if t >= S.count {
18                     t = 1
19                 }
20                 result[t] = c
21                 t += 2
22             }
23         }
24         
25         return String(result)
26     }
27 }

48ms

 1 class Solution {
 2     func reorganizeString(_ S: String) -> String {
 3         typealias Pair = (key: Character, value: Int)
 4         let s = S
 5         if s.count < 1 { return "" }
 6         var dict = [Character: Int]()
 7         // var heap = Heap<Pair> { $0.value > $1.value }
 8         var sorted = [Pair]()
 9         var queue = [Pair]()
10         var result = ""
11 
12         for c in s {
13             dict[c] = (dict[c] ?? 0) + 1
14         }
15 
16         // dict.forEach {
17         //     heap.add($0)
18         // }
19         sorted = dict.sorted { $0.value > $1.value }.map { $0 }
20 
21         while sorted.count > 0 {
22             let top = sorted.removeFirst()
23             result += String(top.key)
24 
25             let count = top.value - 1
26             queue.append((top.key, count))
27 
28             if queue.count > 1 {
29                 let first = queue.removeFirst()
30                 if first.value > 0 {
31                     sorted.append(first)
32                     sorted = sorted.sorted { $0.value > $1.value }
33                 }
34             }
35         }
36 
37         if result.count != s.count {
38             return ""
39         }
40 
41         return result
42     }
43 }

56ms

 1 class Solution {    
 2     func reorganizeString(_ S: String) -> String {
 3         var countByChar = Dictionary<Character, Int>(minimumCapacity:26)
 4         for c in Array(S) {
 5             countByChar[c, default:0] += 1
 6         }
 7         var chars = countByChar.keys.sorted { 
 8             return countByChar[$0]! > countByChar[$1]!
 9         }
10         var t = 0
11         var result = Array(repeating: Character("~"), count: S.count)
12         for c in chars {
13             for _ in 0..<countByChar[c]! {
14                 if countByChar[c]! > (S.count + 1) / 2 {
15                     return ""
16                 }
17                 if t >= S.count {
18                     t = 1
19                 }
20                 result[t] = c
21                 t += 2
22             }
23         }
24         
25         return String(result)
26     }
27 }

68ms

  1 import Foundation
  2 
  3 public struct Heap<T> {
  4     
  5     /** The array that stores the heap's nodes. */
  6     var nodes = [T]()
  7     
  8     /**
  9      * Determines how to compare two nodes in the heap.
 10      * Use '>' for a max-heap or '<' for a min-heap,
 11      * or provide a comparing method if the heap is made
 12      * of custom elements, for example tuples.
 13      */
 14     private var orderCriteria: (T, T) -> Bool
 15     
 16     /**
 17      * Creates an empty heap.
 18      * The sort function determines whether this is a min-heap or max-heap.
 19      * For comparable data types, > makes a max-heap, < makes a min-heap.
 20      */
 21     public init(sort: @escaping (T, T) -> Bool) {
 22         self.orderCriteria = sort
 23     }
 24     
 25     /**
 26      * Creates a heap from an array. The order of the array does not matter;
 27      * the elements are inserted into the heap in the order determined by the
 28      * sort function. For comparable data types, '>' makes a max-heap,
 29      * '<' makes a min-heap.
 30      */
 31     public init(array: [T], sort: @escaping (T, T) -> Bool) {
 32         self.orderCriteria = sort
 33         configureHeap(from: array)
 34     }
 35     
 36     /**
 37      * Configures the max-heap or min-heap from an array, in a bottom-up manner.
 38      * Performance: This runs pretty much in O(n).
 39      */
 40     private mutating func configureHeap(from array: [T]) {
 41         nodes = array
 42         for i in stride(from: (nodes.count/2-1), through: 0, by: -1) {
 43             shiftDown(i)
 44         }
 45     }
 46     
 47     public var isEmpty: Bool {
 48         return nodes.isEmpty
 49     }
 50     
 51     public var count: Int {
 52         return nodes.count
 53     }
 54     
 55     /**
 56      * Returns the index of the parent of the element at index i.
 57      * The element at index 0 is the root of the tree and has no parent.
 58      */
 59     @inline(__always) internal func parentIndex(ofIndex i: Int) -> Int {
 60         return (i - 1) / 2
 61     }
 62     
 63     /**
 64      * Returns the index of the left child of the element at index i.
 65      * Note that this index can be greater than the heap size, in which case
 66      * there is no left child.
 67      */
 68     @inline(__always) internal func leftChildIndex(ofIndex i: Int) -> Int {
 69         return 2*i + 1
 70     }
 71     
 72     /**
 73      * Returns the index of the right child of the element at index i.
 74      * Note that this index can be greater than the heap size, in which case
 75      * there is no right child.
 76      */
 77     @inline(__always) internal func rightChildIndex(ofIndex i: Int) -> Int {
 78         return 2*i + 2
 79     }
 80     
 81     /**
 82      * Returns the maximum value in the heap (for a max-heap) or the minimum
 83      * value (for a min-heap).
 84      */
 85     public func peek() -> T? {
 86         return nodes.first
 87     }
 88     
 89     /**
 90      * Adds a new value to the heap. This reorders the heap so that the max-heap
 91      * or min-heap property still holds. Performance: O(log n).
 92      */
 93     public mutating func insert(_ value: T) {
 94         nodes.append(value)
 95         shiftUp(nodes.count - 1)
 96     }
 97     
 98     /**
 99      * Adds a sequence of values to the heap. This reorders the heap so that
100      * the max-heap or min-heap property still holds. Performance: O(log n).
101      */
102     public mutating func insert<S: Sequence>(_ sequence: S) where S.Iterator.Element == T {
103         for value in sequence {
104             insert(value)
105         }
106     }
107     
108     /**
109      * Allows you to change an element. This reorders the heap so that
110      * the max-heap or min-heap property still holds.
111      */
112     public mutating func replace(index i: Int, value: T) {
113         guard i < nodes.count else { return }
114         
115         remove(at: i)
116         insert(value)
117     }
118     
119     /**
120      * Removes the root node from the heap. For a max-heap, this is the maximum
121      * value; for a min-heap it is the minimum value. Performance: O(log n).
122      */
123     @discardableResult public mutating func remove() -> T? {
124         guard !nodes.isEmpty else { return nil }
125         
126         if nodes.count == 1 {
127             return nodes.removeLast()
128         } else {
129             // Use the last node to replace the first one, then fix the heap by
130             // shifting this new first node into its proper position.
131             let value = nodes[0]
132             nodes[0] = nodes.removeLast()
133             shiftDown(0)
134             return value
135         }
136     }
137     
138     /**
139      * Removes an arbitrary node from the heap. Performance: O(log n).
140      * Note that you need to know the node's index.
141      */
142     @discardableResult public mutating func remove(at index: Int) -> T? {
143         guard index < nodes.count else { return nil }
144         
145         let size = nodes.count - 1
146         if index != size {
147             nodes.swapAt(index, size)
148             shiftDown(from: index, until: size)
149             shiftUp(index)
150         }
151         return nodes.removeLast()
152     }
153     
154     /**
155      * Takes a child node and looks at its parents; if a parent is not larger
156      * (max-heap) or not smaller (min-heap) than the child, we exchange them.
157      */
158     internal mutating func shiftUp(_ index: Int) {
159         var childIndex = index
160         let child = nodes[childIndex]
161         var parentIndex = self.parentIndex(ofIndex: childIndex)
162         
163         while childIndex > 0 && orderCriteria(child, nodes[parentIndex]) {
164             nodes[childIndex] = nodes[parentIndex]
165             childIndex = parentIndex
166             parentIndex = self.parentIndex(ofIndex: childIndex)
167         }
168         
169         nodes[childIndex] = child
170     }
171     
172     /**
173      * Looks at a parent node and makes sure it is still larger (max-heap) or
174      * smaller (min-heap) than its childeren.
175      */
176     internal mutating func shiftDown(from index: Int, until endIndex: Int) {
177         let leftChildIndex = self.leftChildIndex(ofIndex: index)
178         let rightChildIndex = leftChildIndex + 1
179         
180         // Figure out which comes first if we order them by the sort function:
181         // the parent, the left child, or the right child. If the parent comes
182         // first, we're done. If not, that element is out-of-place and we make
183         // it "float down" the tree until the heap property is restored.
184         var first = index
185         if leftChildIndex < endIndex && orderCriteria(nodes[leftChildIndex], nodes[first]) {
186             first = leftChildIndex
187         }
188         if rightChildIndex < endIndex && orderCriteria(nodes[rightChildIndex], nodes[first]) {
189             first = rightChildIndex
190         }
191         if first == index { return }
192         
193         nodes.swapAt(index, first)
194         shiftDown(from: first, until: endIndex)
195     }
196     
197     internal mutating func shiftDown(_ index: Int) {
198         shiftDown(from: index, until: nodes.count)
199     }
200     
201 }
202 
203 extension Heap where T: Equatable {
204     
205     /** Get the index of a node in the heap. Performance: O(n). */
206     public func index(of node: T) -> Int? {
207         return nodes.index(where: { $0 == node })
208     }
209     
210     /** Removes the first occurrence of a node from the heap. Performance: O(n log n). */
211     @discardableResult public mutating func remove(node: T) -> T? {
212         if let index = index(of: node) {
213             return remove(at: index)
214         }
215         return nil
216     }
217     
218 }
219 
220 /*
221  Priority Queue, a queue where the most "important" items are at the front of
222  the queue.
223  The heap is a natural data structure for a priority queue, so this object
224  simply wraps the Heap struct.
225  All operations are O(lg n).
226  Just like a heap can be a max-heap or min-heap, the queue can be a max-priority
227  queue (largest element first) or a min-priority queue (smallest element first).
228  */
229 public struct PriorityQueue<T> {
230     fileprivate var heap: Heap<T>
231     
232     /*
233      To create a max-priority queue, supply a > sort function. For a min-priority
234      queue, use <.
235      */
236     public init(sort: @escaping (T, T) -> Bool) {
237         heap = Heap(sort: sort)
238     }
239     
240     public var isEmpty: Bool {
241         return heap.isEmpty
242     }
243     
244     public var count: Int {
245         return heap.count
246     }
247     
248     public func peek() -> T? {
249         return heap.peek()
250     }
251     
252     public mutating func enqueue(_ element: T) {
253         heap.insert(element)
254     }
255     
256     public mutating func dequeue() -> T? {
257         return heap.remove()
258     }
259     
260     /*
261      Allows you to change the priority of an element. In a max-priority queue,
262      the new priority should be larger than the old one; in a min-priority queue
263      it should be smaller.
264      */
265     public mutating func changePriority(index i: Int, value: T) {
266         return heap.replace(index: i, value: value)
267     }
268 }
269 
270 extension PriorityQueue where T: Equatable {
271     public func index(of element: T) -> Int? {
272         return heap.index(of: element)
273     }
274     
275     public mutating func dequeue(element: T) -> T? {
276         guard peek() != nil else { return nil }
277         let indexToDequeue = index(of: element)!
278         changePriority(index: indexToDequeue, value: peek()!)
279         return dequeue()
280     }
281 }
282 
283 class Solution {
284     func reorganizeString(_ S: String) -> String {
285         guard S.count != 0 else { return "" }
286 
287         // Store char frequency pair into map
288         var map = [Character: Int]()
289 
290         for character in S {
291             map[character] = (map[character] ?? 0) + 1
292         }
293 
294         // push all map entry into priority element, by sorting from high frequency to low frequency. Max Priority queue where highest frequeny elements are first
295         var pq = PriorityQueue<(Character, Int)> { (a, b) -> Bool in
296             return a.1 > b.1
297         }
298         for (key, value) in map {
299             pq.enqueue((key, value))
300         }
301 
302         var result = ""
303 
304         while !pq.isEmpty {
305             // store character with the highest frequency in cache
306             var cache = pq.dequeue()!
307             let resultsArray = Array(result)
308             
309             // if character in cache is different from tail character in current string
310             if result.count == 0 || cache.0 != resultsArray.last {
311                 result.append(cache.0)
312                 cache.1 -= 1
313 
314                 // if the current character still have more frequencies left, push to q
315                 if cache.1 > 0 {
316                     pq.enqueue(cache)
317                 }
318             }
319             // if character in cache is same as tail character in current string
320             // we need to try the character with second highest frequency
321             else {
322                 var cache2 = pq.dequeue()
323                 // corner case: if no more elements in queue, the input string should be invalid
324                 // because we do not have any other characters that different with current string tail
325                 if cache2 == nil {
326                     return ""
327                 }
328 
329                 result.append(cache2!.0)
330                 cache2!.1 -= 1
331 
332                 // if current character still have mor efrequencies left, push to q
333                 // if the current character still have more frequencies left, push to q
334                 if cache2!.1 > 0 {
335                     pq.enqueue(cache2!)
336                 }
337 
338                 //Push top freqeuncy entry into queue as well
339                 pq.enqueue(cache)
340             }
341         }
342         return result
343     }
344 }

96ms

 1 class Solution {
 2     func reorganizeString(_ S: String) -> String {
 3         guard S.count > 2 && S.count <= 500 else {
 4             return S.count > 0 && S.count <= 2 ? S : ""
 5         }
 6         var dict = [Character: Int]()
 7         for char in Array(S) {
 8             if let count = dict[char] {
 9                 dict[char] = count + 1
10             } else {
11                 dict[char] = 1
12             }
13         }
14         var sortedCharInfos = dict.sorted {
15             $0.1 >= $1.1
16         }
17         if let firstCharInfo = sortedCharInfos.first, firstCharInfo.1 > (S.count + 1) / 2 {
18             return ""
19         }
20         var result = ""
21         func addChar(_ index: Int) {
22             guard index < sortedCharInfos.count else {
23                 return
24             }
25             let firstCharInfo = sortedCharInfos[index]
26             result.append(firstCharInfo.key)
27             if sortedCharInfos[index].value == 1 {
28                 sortedCharInfos.remove(at: index)
29             } else {
30                 sortedCharInfos[index] = (firstCharInfo.key, firstCharInfo.value - 1)
31             }
32         }
33         while !sortedCharInfos.isEmpty {
34             if let lastChar = result.last {
35                 sortedCharInfos.sort {
36                     $0.1 >= $1.1
37                 }
38                 if lastChar == sortedCharInfos.first!.key {
39                     addChar(1)
40                 } else {
41                     addChar(0)
42                 }
43             } else {
44                 addChar(0)
45             }
46         }
47         return result
48     }
49 }

猜你喜欢

转载自www.cnblogs.com/strengthen/p/10534876.html