15种算法模式java实现详解

力扣算法实现汇总

1.模式1:双指针(左右指针)

java 复制代码
package com.leetcode.agpattern15;

/**
 * 模式1:双指针(左右指针)
 *
 * 核心思想:
 * 用两个指针从数组/字符串的两端向中间移动,通过条件判断调整指针位置,将O(n²)的暴力解法优化为O(n)
 *
 * 适合场景:
 * 1.数组/字符串的对称问题(如回文串、两数之和 II)
 * 2.有序数组的目标值查找(如三数之和、四数之和)
 * 3.数组的反转、分区问题
 */
public class TwoPointer1 {

    //左右指针通用模版
    public void towPointersLeftRight(int[] nums){
        int left=0;
        int right=nums.length-1;

        while (left<right){
            //核心逻辑:根据条件调整指针
            boolean condition=left< left+1;
            if(condition){
                left++;//左指针右移
            }else{
                right--;//右指针左移
            }

            //特殊场景:去重(如三数之和)
            while (left<right&&nums[left]==nums[left+1]){
                left++;
            }
            while (left<right&&nums[right]==nums[right-1]){
                right--;
            }
        }
    }
}


/**
 * 典型例题
 * LeetCode 15(三数之和)、125(验证回文串)、11(盛最多水的容器)
 */

2.模式2:双指针(快慢指针)

java 复制代码
package com.leetcode.agpattern15;

/**
 * 模式2:双指针(快慢指针)
 * <p>
 * 核心思想:
 * 两个指针以不同速度遍历(快指针走2步,慢指针走1步),用于检测环、找中点、删除倒数第N个元素等
 * <p>
 * 适用场景:
 * 1.链表判圈、找环入口
 * 2. 链表找中点、删除倒数第N个节点
 * 3.数组去重(如移除有序数组中的重复项)
 */
public class TwoPointer2 {
    class ListNode {
        int val;
        ListNode next;
    }

    public void twoPointersSlowFast(ListNode head) {
        ListNode slow = head;
        ListNode fast = head;

        //1.找链表中点
        while (fast != null && fast.next != null) {
            slow = slow.next;//慢指针走1步
            fast = fast.next.next;
        }

        //slow即为链表中点

        //2.判圈(环形链表)
        while (fast != null && fast.next != null) {
            slow = slow.next;
            fast = fast.next.next;
            if (slow == fast) {//相遇则有环
                break;
            }
        }
    }
}
/**
 * 典型例题
 *
 * LeetCode 141(环形链表)、142(环形链表 II)、19(删除链表的倒数第N个节点)
 */

3. 模式3:滑动窗口

java 复制代码
package com.leetcode.agpattern15;

import java.util.HashMap;

/**
 * 模式3:滑动窗口
 *
 * 核心思想:
 * 用左右指针维护一个[窗口],根据窗口内的条件动态扩大/收缩窗口,解决子数组/子串的最值问题
 *
 * 适合场景:
 * 1. 最长无重复字符子串
 * 2. 最小覆盖子串
 * 3.子数组的和/乘积满足条件的问题
 */
public class SlidingWindow3 {
    //滑动窗口通用模版
    public int slidingWindows(String s){
        HashMap<Character,Integer> window=new HashMap<>();
        int left=0,right=0;
        int res=0;//存储结果(长度/数量)

        while (right< s.length()){
            char c= s.charAt(right);
            right++;//扩大窗口
            //窗口内数据更新逻辑
            window.put(c,window.getOrDefault(c,0)+1);

            //满足收缩条件时,收缩窗口
            while (needShrink(window)){
                char d= s.charAt(left);
                left++;//收缩窗口
                //窗口内数据更新逻辑
                window.put(d,window.get(d)-1);
                //更新结果
                res=Math.max(res,right-left);
            }
        }
        return res;
    }

    //收缩条件(需根据题目自定义)
    private boolean needShrink(HashMap<Character, Integer> window) {
        return false;//替换为实际条件(如存在重复字符、窗口和超过目标等)
    }

}


/**
 * 典型例题
 *
 * LeetCode3(无重复字符的最长子串)、76(最小覆盖子串)、209(长度最小的子数组)
 */

4. 模式4:哈希表映射

java 复制代码
package com.leetcode.agpattern15;

import java.util.HashMap;
import java.util.HashSet;

/**
 * 模式4:哈希表映射
 *
 * 核心思想:
 * 用HashMap/HashSet存储[键值对],将查找操作从O(n)优化为O(1),解决计数、去重、映射问题
 *
 * 适用场景:
 * 1.两数之和(数值→索引映射)
 * 2.字母异位词分组(排序后的字符串→原字符串列表)
 * 3.频率统计(元素→出现次数)
 */
public class HashMapping4 {

    //哈希表映射通用模版
    public void hashMapMapping(int[] nums){
        //1.计数/映射场景
        HashMap<Integer,Integer> map=new HashMap<>();
        for(int num:nums){
            //统计频率(简化写法)
            map.put(num,map.getOrDefault(num,0)+1);
        }

        //2.去重场景
        HashSet<Integer> set=new HashSet<>();
        for(int num:nums){
            set.add(num);//自动去重
        }

        //3.查找场景
        int target=9;
        for(int num:nums){
            if(map.containsKey(target-num)){
                //找到匹配项
                System.out.println(num+" + "+(target-num)+ " = "+target);
            }
        }
    }
}
/**
 *典型例题
 *
 * LeetCode1(两数之和)、49(字母异位词分组)、347(前K个高频元素)
 */

5. 模式5:链表虚拟头节点

java 复制代码
package com.leetcode.agpattern15;

/**
 * 模式5:链表虚拟头节点
 *
 * 核心思想:
 * 创建一个虚拟头节点(dummy)指向真实头节点,避免处理[头节点为空/需要删除头节点]的边界问题,统一链表操作逻辑
 *
 * 适用场景
 * 1.合并两个有序链表
 * 2.删除链表中的节点(尤其是头节点)
 * 3.链表插入/反转的边界处理
 */
public class ListDummyNode5 {
    //虚拟头节点通用模版
    class ListNode{
        int val;
        ListNode next;
        ListNode(int val){
            this.val=val;
        }
    }

    public ListNode dummyNodeTemplate(ListNode head){
        //创建虚拟头节点(值无意义,仅用于统一逻辑)
        ListNode dummy=new ListNode(-1);
        dummy.next=head;
        ListNode curr=dummy;//游标节点

        //核心操作(eg:删除值为5的节点)
        while (curr.next!=null){
            if(curr.next.val==5){
                curr.next=curr.next.next;//删除节点
                break;
            }
            curr=curr.next;
        }
        return dummy.next;//返回真实头节点
    }
}
/**
 *典型例题
 * LeetCode21(合并两个有序链表)、19(删除链表的倒数第N个节点)、24(两两交换链表中的节点)
 */

6.模式6:二分查找(普通/边界)

java 复制代码
package com.leetcode.agpattern15;

/**
 * 模式6:二分查找(普通/边界)
 *
 * 核心思想:
 * 将有序数组分成两部分,通过比较中间值与目标值的大小,缩小查找范围,时间复杂度O(logn)
 *
 * 适用场景:
 * 1. 有序数组的目标值查找
 * 2. 找目标值的左/右边界
 * 3.旋转有序数组的查找
 */

//二分查找通用模版(覆盖普通/左边界/右边界)
public class BinarySearch6 {
 //1.普通二分查找(找任意匹配项)
    public int binarySearch(int[] nums,int target){
        int left=0,right=nums.length-1;
        while (left<=right){
            int mid= left+(right-left)/2;//避免溢出
            if(nums[mid] == target){
                return mid;//找到目标
            }else if(nums[mid]<target){
                left= mid+1;
            }else{
                right=mid-1;
            }
        }
        return -1;//未找到
    }

    //2.左边界查找(找第一个>= target位置)
    public int leftBound(int[] nums,int target){
        int left=0,right=nums.length-1;
        while(left<=right){
            int mid=left+(right-right)/2;
            if(nums[mid]>=target){
                right=mid-1;//收缩右边界,找左边界
            }else{
                left=mid+1;
            }
        }
        //检查是否越界
        if(left>=nums.length||nums[left]!=target){
            return -1;
        }
        return left;
    }

    //3.右边界查找(找最后一个<=target的位置)
    public int rightBound(int[] nums,int target){
        int left=0,right=nums.length-1;
        while (left<=right){
            int mid=left+(right-left)/2;
            if(nums[mid]<=target){
                left=mid+1;//收缩左边界,找右边界
            }else{
                right=mid-1;
            }
        }

        //检查是否越界
        if(right<0 || nums[right]!=target){
            return -1;
        }
        return right;
    }
}

/**
 *典型例题
 *LeetCode704(二分查找)、34(在排序数组中查找元素的第一个和最后一个位置)、35(搜索插入位置)
 */

7.模式7:递归与回溯

java 复制代码
package com.leetcode.agpattern15;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

/**
 * 模式7:递归与回溯
 *
 * 核心思想
 * 递归:将大问题拆解为子问题,直到触达终止条件;
 * 回溯:在递归中尝试所有可能的选择,不符合条件时[回退]重新选择
 *
 *适用场景
 * 1.排列/组合/子集问题
 * 2.路径搜索(如二叉树的路径、矩阵中的路径)
 * 3.棋盘问题(如N皇后、数独)
 *
 */
public class RecursiveBacktrack7 {
    //回溯通用模版(排列/组合/子集)
    List<List<Integer>> result= new ArrayList<>();
    LinkedList<Integer> path= new LinkedList<>();//当前路径

    public List<List<Integer>> backtrackTemplate(int[] nums){
        backtrack(nums,0);
        return result;
    }

    private void backtrack(int[] nums, int start) {
        //1.收集结果(根据题目调整:如子集需收集所有路径,排列需收集长度等于nums的路径)
        result.add(new ArrayList<>(path));

        //2.遍历选择列表
        for(int i=start;i<nums.length;i++){
            //剪枝条件(可选,如去重,限制条件)
            if(i>start&&nums[i]==nums[i-1]){
                continue;
            }

            //做出选择
            path.add(nums[i]);
            //递归(排列问题:start=0,需标记已使用;组合问题:start=i+1)
            backtrack(nums,i+1);
            //撤回选择(回溯)
            path.removeLast();
        }
    }
}
/**
 * 典型例题
 * LeetCode46(全排列)、78(子集)、39(组合总和)、131(分割回文串)
 */

8.模式8:贪心算法

java 复制代码
package com.leetcode.agpattern15;

import java.util.Arrays;

/**
 * 模式8:贪心算法
 *
 * 核心思想:
 * 每一步都选择[局部最优]的解,最终期望得到[全局最优]的解(需证明贪心策略的正确性)
 *
 * 适用场景
 * 1.找零问题、活动选择问题
 * 2.区间问题(如无重叠区间、合并区间)
 * 3.字符串拼接、跳跃游戏
 */
public class Greedy8 {
    //贪心算法通用模版(区间问题示例)
    public int greedyTemplate(int[][] intervals){
        if(intervals.length==0){
            return 0;
        }

        //1.排序(贪心策略的核心:按结束时间升序)
        Arrays.sort(intervals,(a,b)->a[1]-b[1]);

        int count=1;//至少选一个区间
        int end=intervals[0][1];//第一个区间的结束时间

        //2.遍历选择局部最优解
        for(int i=1;i<intervals.length;i++){
            if(intervals[i][0]>=end){//不重叠,选择当前区间
                count++;
                end= intervals[i][1];//更新结束时间
            }
        }
        return count;
    }
}
/**
 * 典型例题
 * LeetCode455(分发饼干)、55(跳跃游戏)、435(无重叠区间)、134(加油站)
 */

9.模式9:动态规划(基础)

java 复制代码
package com.leetcode.agpattern15;

/**
 * 模式9:动态规划(基础)
 *
 * 核心思想:将大问题拆解为子问题,存储子问题的解(DP数组),避免重复计算,核心是[状态定义]和[转移方程]
 *
 * 适用场景:
 * 1.最值问题(如最长递增子序列、最大子数组和)
 * 2.计数问题(如爬楼梯、不同路径)
 * 3.背包问题(01背包、完全背包)
 *
 */
public class Dp9 {
   //动态规划通用模版(基础版)
   public int dpTemplate(int[] nums){
       //1.状态定义:dp[i]表示前i个元素的最优解(根据题目调整)
       int[] dp= new int[nums.length];

       //2.初始化条件
       dp[0]=nums[0];
       int max=dp[0];

       //3.状态转移方程
       for(int i=1;i<nums.length;i++){
           //示例:最大子数组和的转移方程
           dp[i]=Math.max(nums[i],dp[i-1]+nums[i]);
           //更新最优解
           max=Math.max(max,dp[i]);
       }
       return max;
   }

   //01背包模版
    public int knapsack01(int[]weight,int[] value,int bagSize){
       //状态定义:dp[j]表示容量为j的背包的最大价值
        int[]dp=new int[bagSize+1];

        //状态转移
        for(int i=0;i<weight.length;i++){
            //倒序遍历,避免重复选择
            for(int j=bagSize;j>=weight[i];j--){
                dp[j]=Math.max(dp[j],dp[j-weight[i]]+value[i]);
            }
        }
        return dp[bagSize];
    }
}
/**
 *典型例题
 * LeetCode70(爬楼梯)、53(最大子数组和)、300(最长递增子序列)、416(分割等和子集)
 */

10.模式10:排序(快速排序/归并排序)

java 复制代码
package com.leetcode.agpattern15;


import java.util.Arrays;

/**
 *模式10:排序(快速排序/归并排序)
 *
 * 核心思想:
 * 快速排序:分治+分区,选择基准值将数组分为两部分
 * 归并排序:分治+合并,先拆分再合并有序子数组
 *
 *
 * 适用场景
 * 1.数组排序(面试手写必考)
 * 2.基于排序的后续处理(如三数之和、字母异位词分组)
 * 3.时间复杂度要求O(nlogn)的场景
 */

//排序模版(快速排序+归并排序)
public class Sort10 {
    //1.快速排序(原地排序,不稳定)
    public void quickSort(int[] nums){
        quickSort(nums,0,nums.length-1);
    }

    private void quickSort(int[] nums, int left, int right) {
        if(left>=right){
            return;
        }
        int pivot=partition(nums,left,right);//分区
        quickSort(nums,left,pivot-1);//左区间
        quickSort(nums,pivot-1,right);//右区间
    }

    private int partition(int[] nums, int left, int right) {
        int pivot=nums[left];//选左边界为基准
        int i=left,j=right;
        while (i<j){
            //右指针找小于基准的值
            while (i<j&& nums[j]>=pivot){
                j--;
            }
            //左指针找大于基准的值
            while (i<j&& nums[i]<=pivot){
                i++;
            }
            //交换
            swap(nums,i,j);
        }
        //基准值归位
        swap(nums,left,i);
        return i;
    }

    private void swap(int[] nums, int i, int j) {
        int temp=nums[i];
        nums[i]=nums[j];
        nums[j]=temp;
    }



    //2.归并排序(稳定排序,需要额外的空间)
    public void mergeSort(int[] nums){
        if(nums.length<=1)
            return;
        int mid=nums.length/2;
        int[]left= Arrays.copyOfRange(nums,0,mid);
        int[] right=Arrays.copyOfRange(nums,mid,nums.length);

        mergeSort(left);
        mergeSort(right);
        mergeSort(nums,left,right);
    }

    private void mergeSort(int[] res, int[] left, int[] right) {
        int i=0,j=0,k=0;
        while (i<left.length&&j<right.length){
            res[k++]=left[i]<=right[j]?left[i++]:right[j++];
        }

        //处理剩余元素
        while (i<left.length){
            res[k++]=left[i++];
        }
        while (j<right.length){
            res[k++]=right[j++];
        }
    }
}
/**
 * 典型例题
 * LeetCode912(排序数组)、148(排序链表)、56(合并区间)
 */

11.模式11:DFS(深度优先搜索)

java 复制代码
package com.leetcode.agpattern15;

import com.java.utils.TreeNode;

/**
 * 模式11:DFS(深度优先搜索)
 *
 * 核心思想:
 * 优先遍历[深度],递归访问节点的所有子节点,直到触达边界,再回溯处理其他分支(可递归/栈实现)
 *
 * 适用场景
 * 1.二叉树的遍历(前/中/后序)
 * 2.图的遍历(如岛屿数量、路径搜索)
 * 3.组合/排列的递归求解
 *
 */

//DFS通用模版(二叉树+图)
public class DFS11 {
    //1.二叉树DFS(前序遍历)
    public void dfsTree(TreeNode root){
        if(root==null){
            return;
        }
        //处理当前节点(前序)
        System.out.println(root.val);
        //递归左子树
        dfsTree(root.left);
        //递归右子树
        dfsTree(root.right);
    }

    //2.图DFS(岛屿数量示例)
    int[][] dirs={{-1,0},{1,0},{0,-1},{0,1}};//上下左右
    public void dfsGrap(char[][] grid,int i,int j){
        // 边界/终止条件
        if(i<0|| i>= grid.length|| j<0 || j>=grid[0].length|| grid[i][j]=='0'){
            return;
        }

        //标记已访问
        grid[i][j]='0';
        //遍历所有方向
        for(int[] dir:dirs){
            int x= i+dir[0];
            int y= j+ dir[1];
            dfsGrap(grid,x,y);
        }
    }
}
/**
 * 典型例题
 * LeetCode94(二叉树中序遍历)、200(岛屿数量)、112(路径总和)
 */

12.BFS(广度优先搜索)

java 复制代码
package com.leetcode.agpattern15;

import com.leetcode.TreeNode;

import java.util.*;

/**
 * BFS(广度优先搜索)
 *
 * 核心思想:
 * 优先遍历[广度],用队列存储当前层的所有节点,遍历完当前层再遍历下一层,适合找[最短路径/最小深度]
 *
 * 适用场景
 * 1.二叉树的层序遍历
 * 2.图的最短路径(如单词接龙、迷宫问题)
 * 3.层级相关的问题(如二叉树的最大深度、找每一层的平均值)
 */

//BFS通用模版(二叉树+图)
public class BFS12 {

    //1.二叉树(层序遍历)
    public List<List<Integer>> bfsTree(TreeNode root){
        List<List<Integer>> result= new ArrayList<>();
        if(root==null){
            return  result;
        }

        Queue<TreeNode> queue=new LinkedList<>();
        queue.offer(root);

        while (!queue.isEmpty()){
            int size=queue.size();//当前层的节点数
            List<Integer> level=new ArrayList<>();

            //遍历当前层
            for(int i=0;i<size;i++){
                TreeNode curr=queue.poll();
                level.add(curr.val);
                //加入下一层节点

                if(curr.left!=null){
                    queue.offer(curr.left);
                }
                if(curr.right!=null){
                    queue.offer(curr.right);
                }
            }
            result.add(level);
        }
        return result;
    }

    //2.图BFS(最短路径示例)
    public int bfsGraph(String beginWord,String endWord,List<String> wordList){
        Set<String> set=new HashSet<>(wordList);
        if(!set.contains(endWord)){
            return 0;
        }

        Queue<String> queue=new LinkedList<>();
        queue.offer(beginWord);
        int step=1;//步长

        while (!queue.isEmpty()){
            int size= queue.size();
            for(int i=0;i<size;i++){
                String curr=queue.poll();
                //处理当前节点(示例:替换字符找下一个单词)
                char[] chars=curr.toCharArray();
                for(int j=0;j<chars.length;j++){
                    char temp=chars[j];
                    for(char c='a';c<= 'z';c++){
                        chars[j]=c;
                        String next=new String(chars);
                        if(next.equals(endWord)){
                            return step+1;
                        }
                        if(set.contains(next)){
                            queue.offer(next);
                            set.remove(next);//标记已访问
                        }
                    }
                    chars[j]=temp;//恢复
                }
            }
            step++;
        }
        return 0;
    }

}
/**
 * 典型例题
 * LeetCode102(二叉树的层序遍历)、127(单词接龙)、104(二叉树的最大深度)
 */

13.模式13:前缀和

java 复制代码
package com.leetcode.agpattern15;

import java.util.HashMap;

/**
 * 模式13:前缀和
 *
 * 核心思想:
 * 预处理一个[前缀和数组],prefix[i]表示前i个元素的和,通过prefix[j]-prefix[i]快速计算区间[i,j)的和,将区间和查询从O(n)优化为O(1)
 *
 * 适用场景:
 * 1.数组的区间和查询
 * 2.子数组的和等于目标值的问题
 * 3.前缀和+哈希表解决子数组和问题
 */

//前缀和通用模版
public class PrefixSum13 {
    //1.基础前缀和(区间和查询)
    public int[] prefixSum(int[] nums){
        int n=nums.length;
        int[] prefix=new int[n+1];//prefix[0]=0,方便计算
        for(int i=0;i<n;i++){
            prefix[i+1]=prefix[i]+nums[i];
        }
        //区间[left,right]的和=prefix[right+1]-prefix[left]
        int left=1,right=3;
        int sum= prefix[right+1]-prefix[left];
        return prefix;
    }

    //2.前缀和+哈希表(子数组和等于k)
    public int subarraySum(int[] nums,int k){
        HashMap<Integer,Integer> map=new HashMap<>();
        map.put(0,1);//前缀和为0的次数初始化为1
        int prefixSum=0,count=0;

        for(int num:nums){
            prefixSum+=num;
            //查找是否存在prefixSum-k
            if(map.containsKey(prefixSum-k)){
                count+= map.get(prefixSum-k);
            }
            //统计当前前缀和的次数
            map.put(prefixSum,map.getOrDefault(prefixSum,0)+1);
        }
        return count;
    }
}
/**
 * 典型例题
 *LeetCode303(区域和检索-数组不可变)、560(和为K的子数组)、974(和可被K整除的子数组)
 */

14.模式14:差分数组

java 复制代码
package com.leetcode.agpattern15;

/**
 * 模式14:差分数组
 *
 * 核心思想:
 *  预处理一个[差分数组],diff[i]=nums[i]-nums[i-1],通过对差分数组的[区间更新],再还原为原数组,将多次区间加减操作从O(n)优化为O(1)
 *
 *
 * 适用场景:
 * 1.多次对数组的某个区间进行加减操作
 * 2.区间更新后求最终数组
 *
 */

//查分数组通用模版
public class Diff14 {
    private int[] diff;//差分数组

    //初始化差分数组
    public Diff14(int[] nums){
        diff=new int[nums.length];
        diff[0]=nums[0];
        for(int i=1;i<nums.length;i++){
            diff[i]=nums[i]-nums[i-1];
        }
    }

    //对区间[i,j]增加val(val可为负数)
    public void increment(int i,int j,int val){
        diff[i]+=val;
        if(j+1<diff.length){
            diff[j+1] -=val;
        }
    }
    //还原为原数组
    public int[] restore(){
        int[] res=new int[diff.length];
        res[0]=diff[0];
        for(int i=1;i<diff.length;i++){
            res[i]= res[i-1] + diff[i];
        }
        return  res;
    }

    //eg:多次区间更新
    public static void main(String[] args) {
        int[] nums={1,2,3,4,5};
        Diff14 dt=new Diff14(nums);
        dt.increment(1,3,2);//区间[1,3]加2
        dt.increment(0,2,-1);//区间[0,2]减1
        int[] res=dt.restore();//结果:// 结果:[0,3,4,6,5]
        for (int re : res) {
            System.out.println("re = " + re);
        }
    }
}
/**
 * 典型例题
 * LeetCode1109(航班预订统计)、370(区间加法)
 */

15. 模式15:堆(优先队列)

java 复制代码
package com.leetcode.agpattern15;

import java.util.Comparator;
import java.util.HashMap;
import java.util.PriorityQueue;

/**
 * 模式15:堆(优先队列)
 *
 * 核心思想:
 * 用堆(优先队列)维护一组元素,快速获取[最大值/最小值],时间复杂度O(logn),适合处理[TopK][中位数]等问题
 *
 * 适用场景
 * 1.前K个高频元素
 * 2.数据流的中位数
 * 3.合并K个有序链表
 */

//堆(优先队列)通用模版
public class Heap15 {
    //1.小顶堆(找前k大的元素)
    public int[] topKFrequent(int[] nums,int k){
        //统计频率
        HashMap<Integer,Integer> freqMap= new HashMap<>();
        for(int num:nums){
            freqMap.put(num,freqMap.getOrDefault(num,0)+1);//getOrDefault:默认找不到为0,能找到+1
        }

        //小顶堆:按频率升序,维护前k个元素
        PriorityQueue<Integer> minHeap=new PriorityQueue<>((a,b)->freqMap.get(a)-freqMap.get(b));

        for(int num:freqMap.keySet()){
            minHeap.offer(num);
            if(minHeap.size()>k){
                minHeap.poll();//弹出最小频率的元素
            }
        }

        //提取结果
        int[] res=new int[k];
        for(int i=k-1;i>=0;i--){
            res[i]=minHeap.poll();
        }
        return res;
    }

    //2.大顶堆(默认:Comparator.reverseOrder())
    public int findKthLargest(int[]nums,int k){
        PriorityQueue<Integer> maxHeap=new PriorityQueue<>(Comparator.reverseOrder());
        for(int num:nums){
            maxHeap.offer(num);
        }
        //弹出k-1次,堆顶即为第k大
        for(int i=0;i<k-1;i++){
            maxHeap.poll();
        }
        return maxHeap.peek();//返回堆顶元素;
    }
}
/**
 *典型例题
 * LeetCode347(前K个高频元素)、215(数组中的第K个最大元素)、295(数据流的中位数)
 */
相关推荐
若尘7971 小时前
数学idea的重构
算法·职场和发展·机器人
思茂信息1 小时前
CST可重构雷达吸波器设计与仿真
网络·算法·平面·智能手机·重构·cst·电磁仿
游乐码1 小时前
c#插入排序
数据结构·算法·排序算法
乐迪信息1 小时前
乐迪信息:AI防爆摄像机,船舶偏航逆行算法实时告警零漏检
大数据·人工智能·物联网·算法·机器学习·计算机视觉·目标跟踪
昵称小白1 小时前
图论专题(上)
算法·深度优先·图论
大大杰哥1 小时前
leetcode hot100(2)双指针,滑动窗口
数据结构·算法·leetcode
skilllite作者1 小时前
GEO 是什么:从搜索引擎到「对话式答案」的信息可见性
java·前端·笔记·安全·搜索引擎·agentskills
是宇写的啊1 小时前
SpringBoot 统一功能处理
java·spring boot·后端
风筝在晴天搁浅1 小时前
LeetCode CodeTop 113.路径总和Ⅱ
算法·leetcode