• [Swift]LeetCode895. 最大频率栈 | Maximum Frequency Stack


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

    Implement FreqStack, a class which simulates the operation of a stack-like data structure.

    FreqStack has two functions:

    • push(int x), which pushes an integer x onto the stack.
    • pop(), which removes and returns the most frequent element in the stack.
      • If there is a tie for most frequent element, the element closest to the top of the stack is removed and returned. 

    Example 1:

    Input: 
    ["FreqStack","push","push","push","push","push","push","pop","pop","pop","pop"],
    [[],[5],[7],[5],[7],[4],[5],[],[],[],[]]
    Output: [null,null,null,null,null,null,null,5,7,5,4]
    Explanation:
    After making six .push operations, the stack is [5,7,5,7,4,5] from bottom to top.  Then:
    
    pop() -> returns 5, as 5 is the most frequent.
    The stack becomes [5,7,5,7,4].
    
    pop() -> returns 7, as 5 and 7 is the most frequent, but 7 is closest to the top.
    The stack becomes [5,7,5,4].
    
    pop() -> returns 5.
    The stack becomes [5,7,4].
    
    pop() -> returns 4.
    The stack becomes [5,7]. 

    Note:

    • Calls to FreqStack.push(int x) will be such that 0 <= x <= 10^9.
    • It is guaranteed that FreqStack.pop() won't be called if the stack has zero elements.
    • The total number of FreqStack.push calls will not exceed 10000 in a single test case.
    • The total number of FreqStack.pop calls will not exceed 10000 in a single test case.
    • The total number of FreqStack.push and FreqStack.pop calls will not exceed 150000 across all test cases.

    实现 FreqStack,模拟类似栈的数据结构的操作的一个类。

    FreqStack 有两个函数:

    • push(int x),将整数 x 推入栈中。
    • pop(),它移除并返回栈中出现最频繁的元素。
      • 如果最频繁的元素不只一个,则移除并返回最接近栈顶的元素。 

    示例:

    输入:
    ["FreqStack","push","push","push","push","push","push","pop","pop","pop","pop"],
    [[],[5],[7],[5],[7],[4],[5],[],[],[],[]]
    输出:[null,null,null,null,null,null,null,5,7,5,4]
    解释:
    执行六次 .push 操作后,栈自底向上为 [5,7,5,7,4,5]。然后:
    
    pop() -> 返回 5,因为 5 是出现频率最高的。
    栈变成 [5,7,5,7,4]。
    
    pop() -> 返回 7,因为 5 和 7 都是频率最高的,但 7 最接近栈顶。
    栈变成 [5,7,5,4]。
    
    pop() -> 返回 5 。
    栈变成 [5,7,4]。
    
    pop() -> 返回 4 。
    栈变成 [5,7]。 

    提示:

    • 对 FreqStack.push(int x) 的调用中 0 <= x <= 10^9
    • 如果栈的元素数目为零,则保证不会调用  FreqStack.pop()
    • 单个测试样例中,对 FreqStack.push 的总调用次数不会超过 10000
    • 单个测试样例中,对 FreqStack.pop 的总调用次数不会超过 10000
    • 所有测试样例中,对 FreqStack.push 和 FreqStack.pop 的总调用次数不会超过 150000。 

    Runtime: 920 ms
    Memory Usage: 22.3 MB
     1 class FreqStack {
     2     var freq:[Int:Int]
     3     var m:[Int:[Int]]
     4     var maxfreq:Int
     5     init() {
     6         freq = [Int:Int]()
     7         m = [Int:[Int]]()
     8         maxfreq = 0        
     9     }
    10     
    11     func push(_ x: Int) {
    12         var f:Int = freq[x,default:0] + 1
    13         freq[x] = f
    14         maxfreq = max(maxfreq, f)
    15         m[f,default:[Int]()].append(x)      
    16     }
    17     
    18     func pop() -> Int {
    19         var x:Int = m[maxfreq,default:[Int]()].popLast() ?? 0
    20         freq[x] = maxfreq - 1
    21         if m[maxfreq,default:[Int]()].count == 0 {maxfreq -= 1}
    22         return x     
    23     }
    24 }
    25 
    26 /**
    27  * Your FreqStack object will be instantiated and called as such:
    28  * let obj = FreqStack()
    29  * obj.push(x)
    30  * let ret_2: Int = obj.pop()
    31  */
    32  

    1016ms

     1 class FreqStack {
     2     
     3     var appearancesByValues = [Int: Int]()
     4     var valuesByAppearances = [Int: [Int]]()
     5 
     6     var maxAppearances = 1
     7     let emptySet = Set<Int>()
     8 
     9     init() {
    10 
    11     }
    12 
    13     func push(_ x: Int) {
    14 
    15         let appearances = self.appearancesByValues[x, default: 0] + 1
    16         self.appearancesByValues[x] = appearances
    17 
    18         if appearances > self.maxAppearances {
    19             self.maxAppearances = appearances
    20         }
    21         self.valuesByAppearances[appearances, default: []].append(x)
    22 
    23     }
    24 
    25     func pop() -> Int {
    26 
    27         let value = (self.valuesByAppearances[self.maxAppearances]?.popLast())!
    28 
    29         self.appearancesByValues[value]! -= 1
    30 
    31         if self.valuesByAppearances[self.maxAppearances]?.count == 0 {
    32             self.maxAppearances -= 1
    33         }
    34 
    35         return value
    36     }
    37 }

    1024ms

     1 class FreqStack {
     2     
     3     var freq: [Int: Int] // num: freq
     4     var group: [Int: [Int]] // freq: stack of elements w/ same freq
     5     var maxFreq: Int
     6 
     7     init() {
     8         self.freq = [Int: Int]()
     9         self.group = [Int: [Int]]()
    10         self.maxFreq = 0
    11     }
    12     
    13     func push(_ x: Int) {
    14         let f = (freq[x] ?? 0) + 1
    15         freq[x] = f
    16         if var stack = group[f] {
    17             stack.append(x)
    18             group[f] = stack
    19         } else {
    20             group[f] = [x]
    21         }
    22         if f > maxFreq {
    23             maxFreq = f
    24         }
    25     }
    26     
    27     func pop() -> Int {
    28         var stack = group[maxFreq]!
    29         let result = stack.removeLast()
    30         freq[result] = maxFreq - 1
    31         group[maxFreq] = stack
    32         if stack.count == 0 {
    33             maxFreq -= 1
    34         }
    35         return result
    36     }
    37 }

    1068ms

     1 class FreqStack {
     2 
     3     init() {
     4         
     5     }
     6     
     7     func push(_ x: Int) {
     8         let f = elem2Freq[x, default: 0] + 1
     9         elem2Freq[x] = f
    10         let sz = subStacks.count
    11         if f >= sz {
    12             subStacks.append([x])
    13         } else {
    14             subStacks[f].append(x)
    15         }
    16     }
    17     
    18     func pop() -> Int {
    19         let sz = subStacks.count
    20         let x = subStacks[sz - 1].popLast()!
    21         if subStacks[sz - 1].isEmpty {
    22             subStacks.removeLast()
    23         }
    24         elem2Freq[x, default: 0] -= 1
    25         return x
    26     }
    27     
    28     var elem2Freq = [Int: Int]()
    29     var subStacks = [[Int]()]
    30 }

    1432ms

      1 public struct PriorityQueue<T: Comparable> {    
      2     fileprivate var heap = [T]()
      3     private let ordered: (T, T) -> Bool
      4     
      5     public init(ascending: Bool = false, startingValues: [T] = []) {
      6         self.init(order: ascending ? { $0 > $1 } : { $0 < $1 }, startingValues: startingValues)
      7     }
      8     
      9     // Creates a new PriorityQueue with the given ordering.
     10     // - parameter order: A function that specifies whether its first argument should
     11     //   come after the second argument in the PriorityQueue.
     12     // - parameter startingValues: An array of elements to initialize the PriorityQueue with.
     13     public init(order: @escaping (T, T) -> Bool, startingValues: [T] = []) {
     14         ordered = order
     15         
     16         //Based on "Heap construction" from Sedgewick p 323
     17         heap = startingValues
     18         var i = heap.count/2 - 1
     19         while i >= 0 {
     20             sink(i)
     21             i -= 1
     22         }
     23     }
     24     
     25     // How many elements the Priority Queue stores
     26     public var count: Int { return heap.count }
     27     
     28     // true if and only if the Priority Queue is empty
     29     public var isEmpty: Bool { return heap.isEmpty }
     30     
     31     // Add a new element onto the Priority Queue. O(lg n)
     32     // - parameter element: The element to be inserted into the Priority Queue.
     33     public mutating func push(_ element: T) {
     34         heap.append(element)
     35         swim(heap.count - 1)
     36     }
     37     
     38     // Remove and return the element with the highest priority (or lowest if ascending). O(lg n)
     39     // - returns: The element with the highest priority in the Priority Queue, or nil if the PriorityQueue is empty.
     40     public mutating func pop() -> T? {
     41         
     42         if heap.isEmpty { return nil }
     43         // added for Swift 2 compatibility
     44         if heap.count == 1 { return heap.removeFirst() } 
     45         // so as not to call swap() with two instances of the same location
     46         heap.swapAt(0, heap.count - 1)
     47         let temp = heap.removeLast()
     48         sink(0)
     49         
     50         return temp
     51     }
     52     
     53     private mutating func sink(_ index: Int) {
     54         var index = index
     55         while 2 * index + 1 < heap.count {            
     56             var j = 2 * index + 1            
     57             if j < (heap.count - 1) && ordered(heap[j], heap[j + 1]) { j += 1 }
     58             if !ordered(heap[index], heap[j]) { break }            
     59             heap.swapAt(index, j)
     60             index = j
     61         }
     62     }
     63     
     64     // Based on example from Sedgewick p 316
     65     private mutating func swim(_ index: Int) {
     66         var index = index
     67         while index > 0 && ordered(heap[(index - 1) / 2], heap[index]) {
     68             heap.swapAt((index - 1) / 2, index)
     69             index = (index - 1) / 2
     70         }
     71     }
     72 }
     73 
     74 struct Entry: Comparable {
     75     let x: Int
     76     let priority: Int
     77     
     78     static func == (lhs: Entry, rhs: Entry) -> Bool {
     79         return lhs.priority == rhs.priority
     80     }
     81     
     82     static func < (lhs: Entry, rhs: Entry) -> Bool {
     83         return lhs.priority < rhs.priority
     84     }
     85     
     86     static func <= (lhs: Entry, rhs: Entry) -> Bool {
     87         return lhs.priority <= rhs.priority
     88     }
     89 
     90     static func > (lhs: Entry, rhs: Entry) -> Bool {
     91         return lhs.priority > rhs.priority
     92     }
     93     
     94     static func >= (lhs: Entry, rhs: Entry) -> Bool {
     95         return lhs.priority >= rhs.priority
     96     }
     97 }
     98 
     99 class FreqStack {
    100     
    101     var pq: PriorityQueue<Entry>
    102     var freq: [Int: Int] = [:]
    103     
    104     init() {
    105         pq = PriorityQueue<Entry>(ascending: false, startingValues: [])
    106     }
    107     
    108     let maxN = 10000
    109     var pushCount = 0
    110     func push(_ x: Int) {
    111         let count = freq[x, default: 0] + 1
    112         freq[x] = count
    113         pushCount += 1
    114         pq.push(Entry(x: x, priority:  count * maxN + pushCount))
    115     }
    116     
    117     func pop() -> Int {
    118         let entry = pq.pop()!
    119         freq[entry.x] = freq[entry.x]! - 1
    120         return entry.x
    121     }
    122 }
    123 
    124 /**
    125  * Your FreqStack object will be instantiated and called as such:
    126  * let obj = FreqStack()
    127  * obj.push(x)
    128  * let ret_2: Int = obj.pop()
    129  */
  • 相关阅读:
    [iOS] 在Storyboard中使用GHSidebarNav侧开菜单控件
    [iOS] UIScrollView与软键盘配合心得——点击空白处隐藏软键盘(完美方案,不增代码)
    MySQL 表解锁
    centos7 两种定时任务
    代码统计工具git_stats部署
    Linux inode索引节点使用率100%解决
    IKVM 0.42.0.3 .NET平台上的Java实现
    Centos7最小化安装后(minimal)安装图形界面
    服务器linux发行版排名
    word为什么总是出现未响应
  • 原文地址:https://www.cnblogs.com/strengthen/p/10605780.html
Copyright © 2020-2023  润新知