zoukankan      html  css  js  c++  java
  • [Swift]LeetCode767. 重构字符串 | Reorganize String

    ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
    ➤微信公众号:山青咏芝(shanqingyongzhi)
    ➤博客园地址:山青咏芝(https://www.cnblogs.com/strengthen/
    ➤GitHub地址:https://github.com/strengthen/LeetCode
    ➤原文地址: https://www.cnblogs.com/strengthen/p/10534876.html 
    ➤如果链接不是山青咏芝的博客园地址,则可能是爬取作者的文章。
    ➤原文已修改更新!强烈建议点击原文地址阅读!支持作者!支持原创!
    ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★

    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 }
  • 相关阅读:
    java语言体系的技术简介之JSP、Servlet、JDBC、JavaBean(Application)
    浅谈HTTP中Get与Post的区别
    浅谈HTTP中Get与Post的区别
    图文混排
    Algorithm: quick sort implemented in python 算法导论 快速排序
    algorithm: heap sort in python 算法导论 堆排序
    Leetcode OJ : Compare Version Numbers Python solution
    Python 同时for遍历多个列表
    Leetcode OJ : Repeated DNA Sequences hash python solution
    Leetcode OJ : Triangle 动态规划 python solution
  • 原文地址:https://www.cnblogs.com/strengthen/p/10534876.html
Copyright © 2011-2022 走看看