js(65)~[692] 前K个高频单词

166 阅读1分钟

力扣本题传送门

最大堆,最小堆,这个算是掌握不了了,一题,看一天,也理解不了哎,就这,这个题解还是我找了比较好理解的,理解不了的还是堆的实现,之前的下沉上浮还能听懂,代码实现蒙蔽了,还的去联系那个最基本的

/*
 * @lc app=leetcode.cn id=692 lang=javascript
 *
 * 
 */

// @lc code=start
/**
 * @param {string[]} words
 * @param {number} k
 * @return {string[]}
 */
var topKFrequent = function (words, k) {
	let map = new Map();
	let heap = [];
	// 1 生成一个map先统计words每个单词出现的频次
	words.forEach(item => {
		map.has(item) ? map.set(item, map.get(item) + 1) : map.set(item, 1)
	})

	// 2 循环map 先把前k个数放到 堆里面 
	let i = 0;
	map.forEach((value, key) => {
		// 循环里面 前k-1个数一次push到堆中 到k-1这个数的时候开始构建堆
		if (i < k) {
			heap.push([key, value]) // key代表次数 value代表字母
			i === k - 1 && buildHeap(map, heap, k)
			// k-1以后的数根堆顶的数比较 比小堆顶堆顶(就是小顶堆最小的数) 大于等于堆顶的数就替换 
		} else if (value > map.get(heap[0][0]) || (value === map.get(heap[0][0]) && key < heap[0][0])) {
			heap[0] = [key, value];
			heapify(map, heap, k, 0);
		}
		i++;
	})


	// 3 heap 排序先比较次数, 相同次数比较字母顺序
	let res = heap.sort((a, b) => {
		// a[1]代表次数 a[0]代表字母
		if (a[1] > b[1]) {
			return -1;
		} else if (a[1] < b[1]) {
			return 1;
		} else {
			// 这里是次数相同
			if (a[0] < b[0]) {
				return -1;
			} else {
				return 1;
			}
		}
	})
	// 循环整理出需要返回的数组 res
	return res.map(item => item[0]);
};

var buildHeap = function (map, arr, len) {
	for (let i = Math.floor(len / 2); i >= 0; i--) {
		heapify(map, arr, len, i);
	}
}
var heapify = function (map, arr, len, i) {
	let l = 2 * i + 1, r = 2 * i + 2, minIndex = i


	// 下面这一行不能生命 声明就报错 替换老师报错
	// let lNode = map.get(arr[l][0]), rNode = map.get(arr[r][0]), mNode = map.get(arr[minIndex][0]);

	// // 次数小或者相等情况排序靠前的置于小堆
	if (l < len && (map.get(arr[l][0]) < map.get(arr[minIndex][0]) || (map.get(arr[l][0]) === map.get(arr[minIndex][0]) && arr[l][0] > arr[minIndex][0]))) { // 次数小或者相等情况排序靠前的置于小堆顶
		minIndex = l
	}
	if (r < len && (map.get(arr[r][0]) < map.get(arr[minIndex][0]) || (map.get(arr[r][0]) === map.get(arr[minIndex][0]) && arr[r][0] > arr[minIndex][0]))) {
		minIndex = r
	}

	if (minIndex !== i) {
		[arr[minIndex], arr[i]] = [arr[i], arr[minIndex]];
		heapify(map, arr, len, minIndex)
	}
}

// @lc code=end