php 解決leetcode 數據流中的第K大元素 php

原題鏈接:703. 數據流中的第K大元素

 

本題主要可以用到最小堆。

 

剛拿到這個題,有下面倆個思路:

 

1、接受參數,設置類屬性,方便add()方法調用。

class KthLargest {
    /**
     * @param Integer $k
     * @param Integer[] $nums
     */
    static $nums;
    public $k;
    function __construct($k, $nums) {
        $this->k = $k;
        $this->nums = $nums;
    }
  
    /**
     * @param Integer $val
     * @return Integer
     */
    function add($val) {
        array_push($this->nums, $val);
        rsort($this->nums);
        return $this->nums[$this->k - 1];
    }
}

但是,這樣有個問題,就是超出時間限制,因爲數據量很大的時候,在規定時間範圍,無法解決。

2、第一個思路,時間超限的原因是每次都要對$this->nums這個數組,進行重新排序,上次已經排序好的,還要再重新排一次,浪費時間。所以,下面的解法是,每次只保存,上次排序完的前k個元素。這次的進行排序的次數就減少了。時間也減少了。

class KthLargest {
    /**
     * @param Integer $k
     * @param Integer[] $nums
     */
    static $nums;
    public $k;
    function __construct($k, $nums) {
        $this->k = $k;
        $this->nums = $nums;
    }
  
    /**
     * @param Integer $val
     * @return Integer
     */
    function add($val) {
        array_push($this->nums, $val);
        rsort($this->nums);
        $this->nums = array_slice($this->nums, 0, $this->k);
        
        return $this->nums[$this->k - 1];
    }
}

運行上面的代碼,可以發現。超出輸出限制。時間超出限制,已經解決。輸出超限制。只好換個方法。看了看評論和題解後,發現可以用最小堆。

正確的解法:

繼承PHP的spl擴展類SplMinHeap。利用最小堆的性質,該最小堆的根結點一定是所有結點中最小的。所以,我們只需要維護K個元素大小的最小堆。只要是大於最小堆的根結點的值$this->top(),就移除該根結點的值$this->extract(),把該值插入最小堆$this->insert($val)。

class KthLargest extends SplMinHeap{
    /**
     * @param Integer $k
     * @param Integer[] $nums
     */
    static $nums;
    public $k;
    function __construct($k, $nums) {
        $this->k = $k;
        遍歷初始化數組,分別插入堆中
        foreach ($nums as $v) {
            $this->add($v);
        }
    }
  
    /**
     * @param Integer $val
     * @return Integer
     */
    function add($val) {
        維持堆的大小爲k,當堆還未滿時,插入數據。
        if ($this->count() < $this->k) {
                $this->insert($val);
            } elseif ($this->top() < $val) {
            //當堆滿的時候,比較要插入元素和堆頂元素大小。大於堆頂的插入。堆頂移除。
                $this->extract();
                $this->insert($val);
            }
        return $this->top();
    }
}

如有問題,請留言。歡迎指正。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章