• 004寻找两个正序数组的中位数


    写在前面,参考的力扣官网题解的解法三,自己用画图的形式解析了这个解法

    二分

    一、java代码

    /*
     * @lc app=leetcode.cn id=4 lang=java
     *
     * [4] 寻找两个正序数组的中位数
     */
    
    // @lc code=start
    class Solution {
        public double findMedianSortedArrays(int[] nums1, int[] nums2) {
            //两个数组的长度确定m,n
            int length1=nums1.length,length2=nums2.length;
            //m+n
            int totalLength=length1+length2;
            //如果总长度为奇数
            if(totalLength%2==1){
                //中位下标
                int midIndex=totalLength/2;
                //找到的即为第k小的值
                double median=getKthElement(nums1,nums2,midIndex+1);
                return median;
    
            //如果总长度为偶数
            }else{
    
                //中位下标1,中位下标2
                int midIndex1=totalLength/2-1,midIndex2=totalLength/2;
                //分别找到中间的两个第k1小,第k2小的值,再求平均
                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小的元素
    //那么就取pivot1=nums1[k/2-1]和pivot2=nums2[k/2-1]进行比较
    //nums1中小于pivot1的原色有nums1[0,...,k/2-2]共计k/2-1个,nums2中同理
    //这样pivot本身最大也只能是第k-1小的元素
    //如果pivot=pivot1,那么nums1[0,...,k/2-1]都不可能是第k小的元素
    //把这些元素删除,剩下的作为nums1数组
    //如果pivot=pivot2,那么nums1[0,...,k/2-1]都不可能是第k小的元素
    //把这些元素删除,剩下的作为nums2数组
    //因为删除了一些元素,所以k的值要改变
    
            //两个数组的长度
            int length1=nums1.length,length2=nums2.length;
            //两个数组的下标
            int index1=0, index2=0;
            //第k小的元素
            int kthElement=0;
    
            while(true){
    
                //边界情况
                if(index1==length1){
    
                    //下标
                    return nums2[index2+k-1];
                }
                if(index2==length2){
                    return nums1[index1+k-1];
                }
    
                //当k=1时,小的那个就是第k
                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;
                }
            }
        }
    
    
    }
    // @lc code=end
    
    

    二、 下面从奇数和偶数两个部分来分析这个算法

    1、 如果m+n为奇数(很简单)

    2、 如果m+n为偶数(当成两个奇数的来求就好了)

  • 相关阅读:
    C++中 destory() 和deallocate()以及delete函数的相关性和区别性
    由STL所想到的 C++显示调用析构函数
    MINIX3 内核整体架构回顾及内核定 性分析
    有一个无效 SelectedValue,因为它不在项目列表中
    SqlParameter.Value = NULL 引发的数据库异常
    前端解决跨域问题的8种方案(最新最全)
    SQL语句优化技术分析 整理他人的
    暂时未整理 已打印
    .Net_把文件数据添加到数据库中(面试题)
    ASP.NET中application对象的用法(面试题)
  • 原文地址:https://www.cnblogs.com/lxr-xiaorong/p/13442492.html
Copyright © 2020-2023  润新知