lc 215. 数组中的第K个最大元素(排序,堆,quick-select

快速选择算法与堆排序实现寻找第k大元素

       思路很多:

    1.将整个数组排序之后的第k个

    2.大小为k的小顶堆

    3.quick-select,即快排的partition函数,每次都能将一个放在应该的位置,如果

    该位置是k-1,那么就是要找的元素

    1.时间:O(nlgn),空间O(1)

    2.时间(nlgk),空间(k)

    3.时间O(kn)???O(n)??

本题要做出来不难,但是要想起到比较好的复习作用,需要做的工作很多:

1我们一般会选择快排,那么和3会共用一个partition函数

而对于快排,要保证o(nlgn) 的时间复杂度,需要确保数组无序,所以需要实现shuffle

而对于2,我们当然可以直接使用java的priorityqueue,但是也可以自己实现堆(以上的内容都是算法4cover到的)

import java.util.Random;

class Solution {
    private void shuffle(int[] nums) {
        Random random = new Random();
        for (int i = nums.length - 1; i > 0; i--) {
            int j = random.nextInt(i + 1);
            swap(nums, i, j);
        }
    }

    private void swap(int[] a, int i, int j) {
        int t = a[i];
        a[i] = a[j];
        a[j] = t;
    }

    // 在[lo,hi]中选一个元素(一般是第一个),然后将所有比他小的移动到他的左边,大的移动到右边
    // 结束时应该左边都是比他小的,右边都是比他大的
    private int partition(int[] nums, int lo, int hi) {
        int pivot = nums[lo];
        int i = lo, j = hi;
        // 扫描范围在[lo,hi],[i,j]组成的范围不断缩小
        while (i <= j) {
            // 从左到右,找到一个比pivot大的,如果找到,停止,如果没有(i指向了hi,扫描了所有的数),也停止
            while (nums[i] <= pivot) {
                i++;
                if (i == hi) {
                    break;
                }
            }
            // 这里同上
            while (nums[j] >= pivot) {
                j--;
                if (j == lo) {
                    break;
                }
            }
            // 如果区间里已经没有数或者是一个数,那么i,j不用再交换,退出循环
            if (i >= j) {
                break;
            }
            swap(nums, i, j);
        }
        // 注意lo是我们的pivot
        // 而j如果不等于lo,那么j是比pivot小的(注意内层循环终止条件),而pivot是最左端的,所以pivot应该和j互换
        // 交换之后,pivot所在的index为j,所以返回j
        swap(nums, lo, j);
        return j;
    }
    // quick select:
    public int findKthLargest(int[] nums, int k) {
       shuffle(nums);
       int lo=0,hi=nums.length-1;
       // 当返回的位置是len-k时结束
       int target=nums.length-k; 
       while(lo<hi){
           int j=partition(nums,lo,hi);
           if(target==j){
               return nums[j];
           }else if(target<j){
               hi=j-1;
           }else if(target>j){
               lo=j+1;
           }
       }
       return nums[target];
    }
}
import java.util.Random;

class Solution {
    private void shuffle(int[] nums) {
        Random random = new Random();
        for (int i = nums.length - 1; i > 0; i--) {
            int j = random.nextInt(i + 1);
            swap(nums, i, j);
        }
    }

    private void swap(int[] a, int i, int j) {
        int t = a[i];
        a[i] = a[j];
        a[j] = t;
    }

    // 在[lo,hi]中选一个元素(一般是第一个),然后将所有比他小的移动到他的左边,大的移动到右边
    // 结束时应该左边都是比他小的,右边都是比他大的
    private int partition(int[] nums, int lo, int hi) {
        int pivot = nums[lo];
        int i = lo, j = hi;
        // 扫描范围在[lo,hi],[i,j]组成的范围不断缩小
        while (i <= j) {
            // 从左到右,找到一个比pivot大的,如果找到,停止,如果没有(i指向了hi,扫描了所有的数),也停止
            while (nums[i] <= pivot) {
                i++;
                if (i == hi) {
                    break;
                }
            }
            // 这里同上
            while (nums[j] >= pivot) {
                j--;
                if (j == lo) {
                    break;
                }
            }
            // 如果区间里已经没有数或者是一个数,那么i,j不用再交换,退出循环
            if (i >= j) {
                break;
            }
            swap(nums, i, j);
        }
        // 注意lo是我们的pivot
        // 而j如果不等于lo,那么j是比pivot小的(注意内层循环终止条件),而pivot是最左端的,所以pivot应该和j互换
        // 交换之后,pivot所在的index为j,所以返回j
        swap(nums, lo, j);
        return j;
    }

    private void quickSort(int[] nums, int lo, int hi) {
        if (lo >= hi) {
            return;
        }
        int p = partition(nums, lo, hi);
        quickSort(nums, lo, p - 1);
        quickSort(nums, p + 1, hi);
    }

    private void quickSort(int[] nums) {
        shuffle(nums);
        quickSort(nums, 0, nums.length - 1);
    }

    public int findKthLargest(int[] nums, int k) {
        quickSort(nums);
        // 升序,返回倒数第k个
        return nums[nums.length-k];
    }

    public static void main(String[] args) {
        int[] a = {1, 2, 3, 4, 5};
        new Solution().quickSort(a);
        System.out.println();
    }
}

 

混合动力汽车(HEV)模型的Simscape模型(Matlab代码、Simulink仿真实现)内容概要:本文档介绍了一个混合动力汽车(HEV)的Simscape模型,该模型通过Matlab代码和Simulink仿真工具实现,旨在对混合动力汽车的动力系统进行建模与仿真分析。模型涵盖了发动机、电机、电池、传动系统等关键部件,能够模拟车辆在不同工况下的能量流动与控制策略,适用于动力系统设计、能耗优化及控制算法验证等研究方向。文档还提及该资源属于一个涵盖多个科研领域的MATLAB仿真资源包,涉及电力系统、机器学习、路径规划、信号处理等多个技术方向,配套提供网盘下载链接,便于用户获取完整资源。; 适合人群:具备Matlab/Simulink使用基础的高校研究生、科研人员及从事新能源汽车系统仿真的工程技术人员。; 使用场景及目标:①开展混合动力汽车能量管理策略的研究与仿真验证;②学习基于Simscape的物理系统建模方法;③作为教学案例用于车辆工程或自动化相关课程的实践环节;④与其他优化算法(如智能优化、强化学习)结合,实现控制策略的优化设计。; 阅读建议:建议使用者先熟悉Matlab/Simulink及Simscape基础操作,结合文档中的模型结构逐步理解各模块功能,可在此基础上修改参数或替换控制算法以满足具体研究需求,同时推荐访问提供的网盘链接获取完整代码与示例文件以便深入学习与调试。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值