問題描述
給一非空的單詞列表,返回前 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);
}
}
}