【Q347】(md) 前K个高频元素
给定一个非空的整数数组,返回其中出现频率前 k 高的元素。
输入: nums = [1,1,1,2,2,3], k = 2
输出: [1,2]
提示:
你可以假设给定的 k 总是合理的,且 1 ≤ k ≤ 数组中不相同的元素的个数。
你的算法的时间复杂度必须优于 O(n log n) , n是数组的大小。
题目数据保证答案唯一,换句话说,数组中前 k 个高频元素的集合是唯一的。
你可以按任意顺序返回答案。
class Solution {
/**
* 【优先队列】【小根堆】
* 很经典的统计问题,通过Map哈希和PriorityQueue优先队列不难实现
*/
public int[] topKFrequent(int[] nums, int k) {
Map<Integer, Integer> map = new HashMap<>();
PriorityQueue<Integer> queue = new PriorityQueue<>((x, y) -> map.get(x)-map.get(y));
for(int n : nums){
if(map.containsKey(n)){
map.put(n, map.get(n) + 1);
}else{
map.put(n, 1);
}
}
for(int n : map.keySet()){
queue.offer(n);
if(queue.size() > k){
queue.poll();
}
}
int[] res = new int[k];
for(int i = 0; i < k; i++){
res[i] = queue.poll();
}
return res;
}
}
【Q94】(md) 二叉树的中序遍历
请使用非递归的写法
class Solution {
/**
*【非递归实现二叉树】
* 指针指向最左的节点,用栈记录这整个过程;
* 当指向null时,开始出栈,并将指针指向右节点
*
* 这样理解:当cur为null,说明左子树已经为null,这是打印中间节点,然后将指针改成其右子树———这恰恰对应中序遍历的思路
*/
public List<Integer> inorderTraversal(TreeNode root) {
List<Integer> list = new ArrayList<>();
Stack<TreeNode> stack = new Stack<>();
TreeNode cur = root;
while (cur != null || !stack.isEmpty()){ // 只有全部遍历完毕后,这里才会取false
while(cur != null){
stack.push(cur);
cur = cur.left;
}
cur = stack.pop();
list.add(cur.val);
cur = cur.right;
}
return list;
}
}
【Q94】(md) 左叶子之和
计算给定二叉树的所有左叶子之和。示例:
3 / \ 9 20 / \ 15 7
在这个二叉树中,有两个左叶子,分别是 9 和 15,所以返回 24
class Solution {
// res就是每个节点对最终结果的贡献————这里作出贡献的不是左叶子本身,而是它的父亲
// 这是因为,一个叶子有可能是右叶子,而这不能从它本身辨认出来,或者说”为时已晚“
// DFS整个树,并尝试加上每一个贡献即可
public int sumOfLeftLeaves(TreeNode root) {
if(root == null){
return 0;
}
int res = (root.left != null && root.left.left == null && root.left.right == null) ? root.left.val : 0;
return res + sumOfLeftLeaves(root.left) + sumOfLeftLeaves(root.right);
}
}
// 还是上当了,开始时从节点本身开始分类讨论,但其实应该从父亲的角度想问题(好怪的说法)
Qs from https://leetcode-cn.com
♠ loli suki
♦ end