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();
    }
}

 

内容概要:本文介绍了一个基于冠豪猪优化算法(CPO)的无人机三维路径规划项目,利用Python实现了在复杂三维环境中为无人机规划安全、高效、低能耗飞行路径的完整解决方案。项目涵盖空间环境建模、无人机动力学约束、路径编码、多目标代价函数设计以及CPO算法的核心实现。通过体素网格建模、动态障碍物处理、路径平滑技术和多约束融合机制,系统能够在高维、密集障碍环境下快速搜索出满足飞行可行性、安全性与能效最优的路径,并支持在线重规划以适应动态环境变化。文中还提供了关键模块的代码示例,包括环境建模、路径评估和CPO优化流程。; 适合人群:具备一定Python编程基础和优化算法基础知识,从事无人机、智能机器人、路径规划或智能优化算法研究的相关科研人员与工程技术人员,尤其适合研究生及有一定工作经验的研发工程师。; 使用场景及目标:①应用于复杂三维环境下的无人机自主导航与避障;②研究智能优化算法(如CPO)在路径规划中的实际部署与性能优化;③实现多目标(路径最短、能耗最低、安全性最高)耦合条件下的工程化路径求解;④构建可扩展的智能无人系统决策框架。; 阅读建议:建议结合文中模型架构与代码示例进行实践运行,重点关注目标函数设计、CPO算法改进策略与约束处理机制,宜在仿真环境中测试不同场景以深入理解算法行为与系统鲁棒性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值