1.滑动窗口最大值
算法思路
1.使用单调队列来解决此题。
2.使最大的元素一直都在队列头部,即:若新加入的元素大于队列中的元素,则将队列中的元素全部移除,再加入新元素。
3. 当然头部的索引需要在【i-k+1,i】之间,否则移除。
注意点
1.注意 if 和while到底用哪个。
2.最后取结果时,要将队列的首元素赋值给result,但是不能直接poll,而是查询peek。
代码
class Solution {
public int[] maxSlidingWindow(int[] nums, int k) {
ArrayDeque<Integer> queue = new ArrayDeque<>();
int result[] = new int[nums.length - k +1];
int index = 0;
for(int i = 0; i<nums.length; i++){
while(!queue.isEmpty() && queue.peek()<i-k+1){
queue.poll();
}
while(!queue.isEmpty() && nums[i]>nums[queue.peekLast()]){
queue.pollLast();
}
queue.offer(i);
if(i>=k-1){
result[index] = nums[queue.peek()];
index++;
}
}
return result;
}
}
2.前K个高频元素
算法思路
1.利用小顶堆的二叉树结构排序,每次将最小的元素弹出,最后小顶堆里积累的才是前k个最大元素。
注意点
1.PriorityQueue 通常是基于二叉堆(一般为小顶堆,也可通过自定义比较器实现大顶堆效果)的数据结构来实现的。
2.队列中是用poll()和offer()或者add()方法,栈中用pop()和push()。
3.Map.Entry 是 Map 接口内部定义的一个接口,它表示 Map 中的一个键值对。可以把它看作是对 Map 中每一组 key-value 的一种抽象封装。
4.通过调用 map.entrySet(),可以方便地遍历 Map 中的所有键值对。
代码
class Solution {
public int[] topKFrequent(int[] nums, int k) {
PriorityQueue<int[]> pq = new PriorityQueue<>((p1, p2) -> p1[1] - p2[1]);
Map<Integer,Integer> map = new HashMap<>();
for(int num:nums) map.put(num, map.getOrDefault(num,0)+1);
for(Map.Entry<Integer,Integer> entry:map.entrySet()){
if(pq.size() < k) {
pq.offer(new int[]{entry.getKey(), entry.getValue()});
} else {
if(entry.getValue() > pq.peek()[1]){
pq.poll();
pq.offer(new int[]{entry.getKey(), entry.getValue()});
}
}
}
int[] result = new int[k];
for(int i=k-1; i>=0; i--){
result[i] = pq.poll()[0];
}
return result;
}
}
3.二叉树的三种深度遍历
算法思路
1.采用递归的方法。
2.递归三要素:①确定递归函数的参数和返回值。②确定终止条件。③确定单层递归的逻辑。
注意点
1.result.add(root.val); 就已经是访问中间节点了。
代码
class Solution {
public List<Integer> preorderTraversal(TreeNode root) {
List<Integer> result = new ArrayList<>();
preorder(root, result);
return result;
}
private void preorder(TreeNode root, List<Integer> result){
if (root == null) return;
result.add(root.val);
preorder(root.left, result);
preorder(root.right, result);
}
}
class Solution {
public List<Integer> postorderTraversal(TreeNode root) {
List<Integer> result = new ArrayList<>();
postorder(root, result);
return result;
}
private void postorder(TreeNode root, List<Integer> result){
if(root == null) return;
postorder(root.left, result);
postorder(root.right, result);
result.add(root.val);
}
}
class Solution {
public List<Integer> inorderTraversal(TreeNode root) {
List<Integer> result = new ArrayList<>();
inorder(root, result);
return result;
}
private void inorder(TreeNode root, List<Integer> result){
if(root == null) return;
inorder(root.left, result);
result.add(root.val);
inorder(root.right, result);
}
}