前K個高頻單詞(leetcode 692)

問題描述

給一非空的單詞列表,返回前 k 個出現次數最多的單詞。

返回的答案應該按單詞出現頻率由高到低排序。如果不同的單詞有相同出現頻率,按字母順序排序。

示例 1:

輸入: [“i”, “love”, “leetcode”, “i”, “love”, “coding”], k = 2
輸出: [“i”, “love”]
解析: “i” 和 “love” 爲出現次數最多的兩個單詞,均爲2次。
注意,按字母順序 “i” 在 “love” 之前。

示例 2:

輸入: [“the”, “day”, “is”, “sunny”, “the”, “the”, “the”, “sunny”, “is”, “is”], k = 4
輸出: [“the”, “is”, “sunny”, “day”]
解析: “the”, “is”, “sunny” 和 “day” 是出現次數最多的四個單詞,出現次數依次爲 4, 3, 2 和 1 次。

注意:
假定 k 總爲有效值, 1 ≤ k ≤ 集合元素數。
輸入的單詞均由小寫字母組成。
來源:力扣(LeetCode)

鏈接:https://leetcode-cn.com/problems/top-k-frequent-words
著作權歸領釦網絡所有。商業轉載請聯繫官方授權,非商業轉載請註明出處。

class Solution {
    protected $heap = [];
    protected $len = null;
    /**
     * @param String[] $words
     * @param Integer $k
     * @return String[]
     */
    function topKFrequent($words, $k) {
        if (empty($words)) {
            return ;
        }
        //構建hashmap
        $map = [];
        foreach ($words as $w) {
            if (isset($map[$w])) {
                $map[$w] += 1;
            } else {
                $map[$w] = 1;
            }
        }

        $arr = [];
        foreach ($map as $word => $num) {
            $arr[] = [
                'word'  => $word,
                'num'   => $num
            ];
        }
        unset($map);

		$len = count($map);
        //構建heap
        for ($i=0; $i<$k; $i++) {
            $this->heap[] = $arr[$i];
        }
        $this->len = count($this->heap);

        $this->create_heap();

        //追加
        for ($i=$k; $i<$len; $i++) {
            if ($this->heap[0]['num'] < $arr[$i]['num']) {
                $this->heap[0] = $arr[$i];
                $this->adjust_heap(0, $len);
            } else if ($this->heap[0]['num'] == $arr[$i]['num']) {
                if ($this->heap[0]['word'] > $arr[$i]['word']) {
                    $this->heap[0] = $arr[$i];
                    $this->adjust_heap(0, $len);
                }
            } else {
                //nothing
            }
        }
        
        //排序
        $this->sort();
         $ret = [];
         foreach ($this->heap as $item) {
             $ret[] = $item['word'];
         }
         return $ret;
    }

    function create_heap()
    {
        $len = count($this->heap);
        for ($i=$len >> 1; $i>=0; $i--) {
            $this->adjust_heap($i);
        }
    }

    /**
     * 根index 調整某棵樹的左右節點
     **/
    function adjust_heap($index)
    {
        $len = $this->len;
        if ($index >= $len) {
            return ;
        }

        $l = ($index << 1) + 1;
        $r = ($index << 1) + 2;
        $min = $index;

        if ($l < $len && $this->heap[$l]['num'] < $this->heap[$min]['num']) {
            $min = $l;
        }
        if ($l < $len && $this->heap[$l]['num'] == $this->heap[$min]['num'] && $this->heap[$l]['word'] > $this->heap[$min]['word']) {
            $min = $l;
        }

        if ($r < $len && $this->heap[$r]['num'] < $this->heap[$min]['num']) {
            $min = $r;
        }
        if ($r < $len && $this->heap[$r]['num'] == $this->heap[$min]['num'] && $this->heap[$r]['word'] > $this->heap[$min]['word']) {
            $min = $r;
        }

        if ($min != $index) {
            list($this->heap[$index], $this->heap[$min]) = [$this->heap[$min], $this->heap[$index]];
            $this->adjust_heap($min);
        }
    }

    public function sort()
    {
        $len = count($this->heap);
        for ($i = $len - 1; $i>0; $i--) {
            list($this->heap[0], $this->heap[$i]) = [$this->heap[$i], $this->heap[0]];
            $this->len -= 1;
            $this->adjust_heap(0);
        }
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章