12.27 算法练习

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); 就已经是访问中间节点了。

代码

/** 前序
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
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);

    }
}

/** 后序
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
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);
    }
}
/** 中序
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
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);

      }

    
}

你可能感兴趣的:(算法,java,数据结构)