Leetcode hot100之“结合递归+二分“题目详解

news2024/11/29 8:50:59

1 总结

题目 215 (“数组中的第 K 个最大元素”) 和题目 4 (“寻找两个正序数组的中位数”) 之间的联系主要体现在它们都涉及到寻找一个有序集合中的第 k 个元素的问题。尽管这两个问题的具体应用场景和所处理的数据结构不同,它们共享相似的算法思想和技术。

题目 215 - 数组中的第 K 个最大元素

此题的解决方案涉及到快速选择算法,这是快速排序的一个变体。快速选择算法通过选择一个枢轴来划分数组,并基于枢轴的位置来决定继续在左边或右边搜索目标元素。该方法的目标是找到数组中第 k 个最大的元素。

题目 4 - 寻找两个正序数组的中位数

在这个问题中,目标是找到两个有序数组合并后的中位数。解决方案同样涉及到一种选择方法,即在两个数组中找到第 k 小的元素。这通常通过二分查找来实现,需要在两个数组中找到合适的分割线,以确保左右两侧元素的数量相等(或相差一个)。

共同点

  1. 有序集合中的元素选择:两个问题都涉及到在有序集合中选择特定顺序的元素(第 k 个最大或第 k 个最小)。

  2. 分治和递归思想:这两个问题都可以通过分治法和递归思想来解决。在问题 215 中,快速选择通过递归地划分数组来找到第 k 个最大元素;在问题 4 中,二分查找通过递归或迭代的方式在两个数组中找到正确的中位数位置。

  3. 时间复杂度优化:这两个问题的高效解法都不需要完整地排序整个数组或合并两个数组,而是通过局部排序或局部选择来达到目的,从而优化了时间复杂度。

结论

尽管题目 215 和题目 4 处理的具体问题不同,但它们在算法实现上有着类似的思想和技术。这表明了在算法设计中,不同的问题往往可以通过共享的核心算法思想来解决。

2 题目一:215. 数组中的第K个最大元素

在这里插入图片描述

2.1 答案

做这道题之前,建议先做一下快排,非常有帮助,912. 排序数组

2.1.1 方法一

    public int findKthLargest(int[] nums, int k) {
        int n=nums.length;

        List<Integer>list=new ArrayList<>();
        for(int i=0;i<n;i++){
            list.add(nums[i]);
        }
        int ans=dfs(list,k);
        return ans;
    }

    int dfs(List<Integer>list,int p){

        Random rand=new Random();
        
        int base=list.get(rand.nextInt(list.size()));

        List<Integer>s=new ArrayList<>();
        List<Integer>m=new ArrayList<>();
        List<Integer>l=new ArrayList<>();

        for(int k=0;k<list.size();k++){
            if(list.get(k)<base){
                s.add(list.get(k));
            }else if(list.get(k)==base){
                m.add(list.get(k));
            }else{
                l.add(list.get(k));
            }
        }
        // 在数组中的第p大等于在数组中的第list.size()-p+1大
        if(s.size()>=list.size()-p+1){
            // 第二个参数决定在small数组中,这个数是第几大的数
            return dfs(s,s.size()-(list.size()-p+1)+1);
        }else if(s.size()+m.size()>=list.size()-p+1){
            return m.get(0);
        }else{
            return dfs(l,p);
        }
    }

2.1.2 方法二

   public int findKthLargest(int[] nums, int k) {
        int n=nums.length;
        
        List<Integer>list=new ArrayList<>();
        for(int i=0;i<n;i++){
            list.add(nums[i]);
        }
        int ans=dfs(list,k);
        return ans;
    }

    // 使用不同的划分区间算法,将数组划分成三个区域:小于、等于和大于
    int dfs2(int[]nums,int l, int r, int k){
        Random rand=new Random();
        int pivot=nums[l];
        int p=l,q=r;
        for(int i=l;i<=r;){
            if(nums[i]>pivot){
                swap(nums,i,q--);
            }else if(nums[i]<pivot){
                swap(nums,i,p++);
            }else{
                i++;
            }
        }
        int len=r-l+1;
        if(p>=len-k+1){
            return dfs2(nums,l,p-1,p-(len-k+1)+1);
        }else if(q>=len-k+1){
            return dfs2(nums,q+1,r,k);
        }else{
            return nums[q];
        }
    }

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

3 问题二:4. 寻找两个正序数组的中位数

在这里插入图片描述

3.1 答案

     public double findMedianSortedArrays2(int[] nums1, int[] nums2) {
        int length1 = nums1.length, length2 = nums2.length;
        int totalLength = length1 + length2;
        if (totalLength % 2 == 1) {
            int midIndex = totalLength / 2;
            double median = getKthElement(nums1, nums2, midIndex + 1);
            return median;
        } else {
            int midIndex1 = totalLength / 2 - 1, midIndex2 = totalLength / 2;
            double median = (getKthElement(nums1, nums2, midIndex1 + 1) + getKthElement(nums1, nums2, midIndex2 + 1)) / 2.0;
            return median;
        }
    }

    public int getKthElement(int[] nums1, int[] nums2, int k) {
        /* 主要思路:要找到第 k (k>1) 小的元素,那么就取 pivot1 = nums1[k/2-1] 和 pivot2 = nums2[k/2-1] 进行比较
         * 这里的 "/" 表示整除
         * nums1 中小于等于 pivot1 的元素有 nums1[0 .. k/2-2] 共计 k/2-1 个
         * nums2 中小于等于 pivot2 的元素有 nums2[0 .. k/2-2] 共计 k/2-1 个
         * 取 pivot = min(pivot1, pivot2),两个数组中小于等于 pivot 的元素共计不会超过 (k/2-1) + (k/2-1) <= k-2 个
         * 这样 pivot 本身最大也只能是第 k-1 小的元素
         * 如果 pivot = pivot1,那么 nums1[0 .. k/2-1] 都不可能是第 k 小的元素。把这些元素全部 "删除",剩下的作为新的 nums1 数组
         * 如果 pivot = pivot2,那么 nums2[0 .. k/2-1] 都不可能是第 k 小的元素。把这些元素全部 "删除",剩下的作为新的 nums2 数组
         * 由于我们 "删除" 了一些元素(这些元素都比第 k 小的元素要小),因此需要修改 k 的值,减去删除的数的个数
         */

        int length1 = nums1.length, length2 = nums2.length;
        int index1 = 0, index2 = 0;
        int kthElement = 0;

        while (true) {
            // 边界情况
            if (index1 == length1) {
                return nums2[index2 + k - 1];
            }
            if (index2 == length2) {
                return nums1[index1 + k - 1];
            }
            if (k == 1) {
                return Math.min(nums1[index1], nums2[index2]);
            }
            
            // 正常情况
            int half = k / 2;
            int newIndex1 = Math.min(index1 + half, length1) - 1;
            int newIndex2 = Math.min(index2 + half, length2) - 1;
            int pivot1 = nums1[newIndex1], pivot2 = nums2[newIndex2];
            if (pivot1 <= pivot2) {
                k -= (newIndex1 - index1 + 1);
                index1 = newIndex1 + 1;
            } else {
                k -= (newIndex2 - index2 + 1);
                index2 = newIndex2 + 1;
            }
        }
    }

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1215905.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

系列十、堆参数调优

一、堆内存调优参数 -Xms堆空间的最小值&#xff0c;默认为物理内存的1/64-Xmx堆空间的最大值&#xff0c;默认为物理内存的1/4-XX:PrintGCDetails输出详细的GC处理日志 二、获取堆内存的默认物理内存 /*** Author : 一叶浮萍归大海* Date: 2023/11/16 14:50* Description: 获…

基于springboot的医护人员排班系统 全套代码 全套文档

基于springboot的医护人员排班系统,springboot vue mysql (毕业论文10411字以上,共27页,程序代码,MySQL数据库) 代码下载链接&#xff1a;https://pan.baidu.com/s/177HdCGtTvqiHP4O7qWAgxA?pwd0jlf 提取码&#xff1a;0jlf 【运行环境】 IDEA, JDK1.8, Mysql, Node, Vue …

荣誉榜再度添彩!热烈祝贺旭帆科技荣获安徽省大数据企业!

2023年11月3日&#xff0c;安徽省数据资源管理局网站发布《关于2023年度安徽省大数据企业名单的公示》&#xff0c;经企业申报、各市初审推荐、专家评审、审查认定等程序&#xff0c;安徽旭帆信息科技有限公司&#xff08;以下简称“旭帆科技”&#xff09;凭借在视频大数据应用…

[PyTorch][chapter 63][强化学习-时序差分学习]

目录&#xff1a; 蒙特卡罗强化学习的问题 基于转移的策略评估 时序差分评估 Sarsa-算法 Q-学习算法 一 蒙特卡罗强化学习的的问题 有模型学习&#xff1a; Bellman 等式 免模型学习: 蒙特卡罗强化学习 迭代&#xff1a; 使用策略 生成一个轨迹&#xff0c; for t…

VMware17虚拟机Linux安装教程(详解附图,带VMware Workstation 17 Pro安装)

一、安装 VMware 附官方下载链接&#xff08;VM 17 pro&#xff09;&#xff1a;https://download3.vmware.com/software/WKST-1701-WIN/VMware-workstation-full-17.0.1-21139696.exe 打开下载好的VMware Workstation 17 Pro安装包&#xff1b; 点击下一步&#xff1b; 勾选我…

损失函数——KL散度(Kullback-Leibler Divergence,KL Divergence)

KL散度&#xff08;Kullback-Leibler Divergence&#xff0c;简称KL散度&#xff09;是一种度量两个概率分布之间差异的指标&#xff0c;也被称为相对熵&#xff08;Relative Entropy&#xff09;。KL散度被广泛应用于信息论、统计学、机器学习和数据科学等领域。 KL散度衡量的…

kafka个人笔记

大部分内容源于https://segmentfault.com/a/1190000038173886, 本人手敲一边加强印象方便复习 消息系统的作用 解耦 冗余 扩展性 灵活性&#xff08;峰值处理 可恢复 顺序保证 缓冲 异步 解耦&#xff1a;扩展两边处理过程&#xff0c;只需要让他们遵守约束即可冗余&#xf…

ubuntu 20通过docker安装onlyoffice,并配置https访问

目录 一、安装docker &#xff08;一&#xff09;更新包列表和安装依赖项 &#xff08;二&#xff09;添加Docker的官方GPG密钥 &#xff08;三&#xff09;添加Docker存储库 &#xff08;四&#xff09;安装Docker &#xff08;五&#xff09;启动Docker服务并设置它随系…

MySQL覆盖索引的含义

覆盖索引&#xff1a;SQL只需要通过索引就可以返回查询所需要的数据&#xff0c;而不必通过二级索引查到主键之后再去查询数据&#xff0c;因为查询主键索引的 B 树的成本会比查询二级索引的 B 的成本大。 也就是说我select的列就是我的索引列&#xff08;或者主键&#xff0c;…

整理笔记——MOS管、三极管、IGBT

一、MOS管 在实际生活要控制点亮一个灯&#xff0c;例如家里的照明能&#xff0c;灯和电源之间就需要一个开关需要人为的打开和关闭。 再设计电路板时&#xff0c;如果要使用MCU来控制一个灯的开关&#xff0c;通常会用mos管或是三极管来做这个开关元件。这样就可以通过MCU的信…

填充每个节点的下一个右侧节点指针

题目链接 填充每个节点的下一个右侧节点指针 题目描述 注意点 给定一个 完美二叉树 解答思路 广度优先遍历一层层的遍历二叉树&#xff0c;将每一层节点的next指针都指向右侧节点 代码 class Solution {public Node connect(Node root) {if (root null) {return null;}…

【YOLOX简述】

YOLOX的简述 一、 原因1. 背景2. 概念 二、 算法介绍2.1 YOLOX算法结构图&#xff1a;2.2 算法独特点2.3 Focus网络结构2.4 FPN&#xff0c;PAN2.5 BaseConv2.6 SPP2.7 CSPDarknet2.8 YOlO Head 三、预测曲线3.1 曲线 一、 原因 1. 背景 工业的缺陷检测是计算机视觉中不可缺少…

2022年第八届美亚杯个人赛复盘

以学生的身份最后一次打美亚杯了还是要记录一下的写个wp告别哈哈。 1.[单选题] 王晓琳在这本电子书籍里最后对哪段文字加入了重点标示效果(Highlight)?(2分) A. 卿有何妙计 B. 宝玉已是三杯过去了 C. 武松那日早饭罢 D. 就除他做个强马温罢 2.[多选题] 王晓的手机里有一个 …

c#之反射详解

总目录 文章目录 总目录一、反射是什么&#xff1f;1、C#编译运行过程2、反射与元数据3、反射的优缺点 二、反射的使用1、反射相关的类和命名空间1、System.Type类的应用2、System.Activator类的应用3、System.Reflection.Assembly类的应用4、System.Reflection.Module类的应用…

销售管道管理软件推荐:提升销售业绩与效率

在企业中销售部门扮演着锐意进取的尖刀部队的角色&#xff0c;肩负着拓展公司发展领土的重要责任。销售管理是一个漫长而复杂的过程&#xff0c;需要经历潜在的商机、联系跟进、签订合同以及赢得订单等关键里程碑&#xff0c;无论是面向C端用户的销售还是面向企业复杂产品的销售…

TSINGSEE青犀AI智能分析+视频监控工业园区周界安全防范方案

一、背景需求分析 在工业产业园、化工园或生产制造园区中&#xff0c;周界防范意义重大&#xff0c;对园区的安全起到重要的作用。常规的安防方式是采用人员巡查&#xff0c;人力投入成本大而且效率低。周界一旦被破坏或入侵&#xff0c;会影响园区人员和资产安全&#xff0c;…

前台页面从数据库中获取下拉框值

后端&#xff1a;查询所有信息 前台&#xff1a;elementUI <el-select v-model"searchData.stationName" clearable> <el-option :label"item.stationName" :value"item.stationName" v-for"item in stationNameList&quo…

根据店铺ID/店铺链接/店铺昵称获取京东店铺所有商品数据接口|京东店铺所有商品数据接口|京东API接口

要获取京东店铺的所有商品数据&#xff0c;您需要使用京东开放平台提供的API接口。以下是一些可能有用的API接口&#xff1a; 商品SKU列表接口&#xff1a;该接口可以获取指定店铺下的所有商品SKU列表&#xff0c;包括商品ID、名称、价格等信息。您可以使用该接口来获取店铺中…

SpringBoot3新特性

本篇文章参考尚硅谷springboot3课程: https://www.bilibili.com/video/BV1Es4y1q7Bf?p94&vd_sourced6deb2b69988de2ae72087817e5143d7 原版笔记: https://www.yuque.com/leifengyang/springboot3/xy9gqc2ezocvz4wn 1.自动配置包位置变化 现在指定自动配置类放在了下面这…

俄罗斯方块小游戏

框架 package 框架;import java.awt.image.BufferedImage; import java.util.Objects;/*** author xiaoZhao* date 2022/5/7* describe* 小方块类* 方法&#xff1a; 左移、右移、下落*/ public class Cell {// 行private int row;// 列private int col;private BufferedIm…