数据结构、刷leetcode返航版--二分【有序】5/7、5/9、5/11、5/12

1.排序【排序是稳定的:两个相同的数,排序后相对位置不变:快排不稳定;归并稳定】

快排:

第一章 基础算法(一) - AcWing

如何调整范围

经典二分

递归结束条件;条件满足时,进行处理;递归左边,递归右边

递归函数包含什么:结束条件【l==r】,对情况的处理,递归函数的调用。

分界点划分可以是l,r,(l+r)/2,但是如果是选l,比如是1,2排序,i最后结束循环是1,然后最后递归也是sort(q,0,0)

其实有太多问题:>=和>的选择,要不要判断i<j,递归使用i,i-1还是j,j+1【前一个超时了】,先这样吧,想不通。。。。。?????

GOT IT!

按照l<r递归的原则, q[i]</>x的原则【记住】

swap之前记得判断一下i和j,i有可能超过j,就不应该swap了

模版:

void sort(vector<int>&nums,int l,int r){//感觉情况有点多啊
    if(l>=r){
        return;
    }
    int i = l-1;
    int j = r+1;
    int x = nums[(l+r)/2];
    while(i<j){
        do{
            i++;
        }while(nums[i]<x);//不是<=,如果=x应该让他放在中间 
        do{
            j--;
        } while(nums[j]>x);//不是<=
        if(i<j) swap(nums[i],nums[j]);//必须i<j
    }//i>=j j,i
    sort(nums,l,i-1);
    sort(nums,i,r);
}
 

#include<iostream>
#include<algorithm>
using namespace std;

void sort1(vector<int>&nums,int l,int r){
    if(l==r){
        return;
    }
    int mid = nums[(l+r+1) >> 1];
    int i = l-1;
    int j = r+1;
    while(i<j){
        do{i++;}while(nums[i]<mid);
        do{j--;}while(nums[j]>mid);
        if(i<j){
            swap(nums[i],nums[j]);
        }
    }
    // sort(l,mid-1);
    // sort(mid,r);
    sort1(nums,l,i-1);
    sort1(nums,i,r);
}

int main(){
    int n;
    cin>>n;
    vector<int>nums(n);//初始化错误
    for(int i = 0;i<n;i++){
        cin>>nums[i];
    }
    sort1(nums,0,n-1);
    for(int i = 0;i<n;i++){
        cout<<nums[i]<<" ";
    }
    // int l = 0;
    // int r = n-1;
    // int mid;
    // while(l<r){//中间点,小于,大于,交换,左边小于等于,右边大于等于
    //     mid = l+r >> 1;
    //     sort(nums,l,mid);
    //     sort(nums,mid+1,r);
        
    // }
}

关于i,j先-1,在do-while:

while(q[i]<x) i++ ;
因为这里是先判断后 + 1,当q[i] == x == q[j],且 i < j 时,q[i] 与 q[j] 交换之后,其实本质时并没有变化的,但是此时你的while循环会不断重复上述操作,导致你的 i 不会继续+ 1,同理你的 j 也不会 - 1,这段while语句永远在死循环,TLE时必然的。
而while (q[ ++i ]<x) ;可以保证 i 会继续向后遍历,j 同理 。

冒泡排序:
每一次把max数放到最后一位

void bubble_sort(int q[], int n) {
    bool flag = true;
    while (flag) {
        flag = false;
        for (int i = 1; i < n; i++) {
            if (q[i] > q[i + 1]) {
                flag = true;
                int t = q[i];
                q[i] = q[i + 1];
                q[i + 1] = t;
            }
        }
    }
}

归并排序

注意:之后合并还是依赖于nums,所以要把tmp复制回去nums!!

#include<iostream>
#include<algorithm>
#include<vector>

using namespace std;
void merge_sort(vector<int>&nums,int l,int r,vector<int>&tmp){//分,治,和
    if(l == r){
        return;
    }
    int mid = (l+r)>>1;
    merge_sort(nums,l,mid,tmp);
    merge_sort(nums,mid+1,r,tmp);
    //和
    int i = l;int j = mid+1;int k = l;
    while(i<=mid && j<=r){
        if(nums[i]>nums[j]){
            tmp[k++] = nums[j++];
        }else{
            tmp[k++] = nums[i++];
        }
    }
    while(i<=mid){//余下的
        tmp[k++] = nums[i++];
    }
    while(j<=r){//余下的
        tmp[k++] = nums[j++];
    }//排序操作仍然依赖nums
    for(int i = l;i<=r;i++){
        nums[i] = tmp[i];
    }
}

int main(){
    int n;
    cin>>n;
    vector<int>nums(n);
    vector<int>tmp(n);
    for(int i = 0;i<n;i++){
        cin>>nums[i];
    }
    merge_sort(nums,0,n-1,tmp);
    for(int i = 0;i<n;i++){
        cout<<tmp[i]<<" ";
    }
}

2、搜索插入位置【实际1h+】

刷题论 04|二分查找,你根本不需要背那么多模板_哔哩哔哩_bilibili

35. 搜索插入位置 - 力扣(LeetCode)

迷茫了5/7

---------------------------------------------

需要注意最好(l+r)/2用l+((r-l)>>2)代替,防止溢出

最优思路:刚开始没想到可以只是先找target,找不到位置就是l【自己举例子】

int findIndex1(vector<int>& nums, int l, int r, int target) {

        if (l > r) {//[l,r]大于和大于等于【1,3,5,6,target= 7,l>=r返回的是3而非4】,如果用【1,r】理论看的话,l是可以等于r的,没必要返回循环

            return l;

        }

        int m = l + ((r - l) >>2);

        if (nums[m] == target) {

            return m;

        } else if (nums[m] < target) {

            return findIndex1(nums, m + 1, r, target);

        } else {

            return findIndex1(nums, l, m - 1, target);

        }

    }

原来的想法是在每次二分查找中如果找不到target,直接找到 一侧小一侧大的那个位置,然后就不知道循环结束条件是什么了,确实也不需要了,不过自己考虑时问题挺多

考虑成了m-1小于target而m+1大于target【应该是m】

0前面插入和nums.size()-1后面插入的逻辑没考虑清楚

int findIndex(vector<int>& nums, int l, int r, int target) {
       // if (l > r) {
            // 当 l > r 时,说明 target 应插入到 l 的位置
        //    return l;
        }
//
        int m = l + (r - l) / 2;

        if (nums[m] == target) {
            return m; // 直接找到目标
        }

        // 检查是否满足插入条件:nums[m-1] < target < nums[m]
        if (m > 0 && nums[m-1] < target && nums[m] > target) {
            return m; // 插入到 m 的位置
        }

        // 处理边界情况(如插入到数组最左或最右)
        if (m == 0 && nums[m] > target) return 0;
        if (m == nums.size() - 1 && nums[m] < target) return m + 1;

        // 递归搜索左半部分或右半部分
        if (nums[m] < target) {
            return findIndex(nums, m + 1, r, target);
        } else {
            return findIndex(nums, l, m - 1, target);
        }
    }

 模版:简单二分,数组中不包含重复元素, 思考:定义是[l,r]闭区间,跳出循环条件:l > r,l / r = mid +-1;

5/9重做版:套y总模版【10min】

问题:1.l = mid+1可能导致越界,例子[1,3] target = 2;方法就是先去判断一下有没有越界。

预防措施:未知

!!!!“搜索数的范围”之所以没写是因为刚开始他写的是(l+r)>>1,不会越界;

所以还是有(l+r+1)>>1时,还是先判断一下l是否会越界,再判断nums[l]和target的关系

2.关于如果没找到怎么办,刚开始没找到规律,就试了一个数;

但是发现有几个例子不对;

其实可以直接写if,如果大于怎么样小于怎么样,不用猜测

class Solution {
public:
    int searchInsert(vector<int>& nums, int target) {
        int l = 0;
        int r = nums.size()-1;
        int mid;
        while(l<r){
            mid = (l+r+1) >> 1;
            if(nums[mid] == target){
                return mid;
            }else if(nums[mid] > target){
                r = mid-1;
            }else{
                l = mid + 1;//越界了
            }
        }
        if(l>=nums.size()){
            return l;
        }
        if(nums[l] == target){
            return l;
        }
        // else{
        //     return l+1;
        // }//鲁莽了,还是可以先比较一下大小的
        else if(nums[l]>target){
            return l;
        }else{
            return l+1;
        }
    }
};

3.搜索二维矩阵【12min】

74. 搜索二维矩阵 - 力扣(LeetCode)

问题:1.“==”写成了“=”

2.k++没写

//得到m*n矩阵的m/n

vector<vector<int>>matrix;

m = matrix.size();

n = matrix[0].size();

class Solution {
public:
    bool searchMatrix(vector<vector<int>>& matrix, int target) {
        //非严格递增顺序排列
        int m = matrix.size();
        int n = matrix[0].size();
        // cout<<"m"<<m<<"n"<<n<<endl;
        vector<int>nums(m*n);
        int k = 0;
        for(int i = 0;i<m;i++){
            for(int j= 0;j<n;j++){
                nums[k] = matrix[i][j];
                k++;//?没写
            }
        }
        int l = 0;
        int r = nums.size()-1;
        int mid;
        // int mid = (l+r+1) >> 1;//[[1]]
        while(l<r){
            mid = (l+r+1) >> 1;
            if(nums[mid]<target){
                l = mid+1;
            }else if(nums[mid]>target){
                r = mid-1;
            }else{
                return true;
            }
        }
        if(l == nums.size()){//[[1]]只是因为==写成了=
            // cout<<nums.size();
            return false;
        }
        if(nums[l] == target){
            return true;
        }else{
            return false;
        }
        
    }
};

4.数的范围【5/9】

789. 数的范围 - AcWing题库

一个很严重的问题,变量定义到后面就忘记什么是什么了,比如vec数组后面就变成了q[i],target变成了q.......

理解!!!!!【开心,狂喜,兴奋,感觉自己强的可怕】在这个题里面,先做的其实是找到第一个符合target的数,==target时,前面可能还有数,所以==taget时,应该找l,mid,和>target归为一类;

同理,后面要找的是最后一个符合target的数,==target时,后面还可能有数,所以==taget时,应该找mid,r,和<target归为一类;

注意对应模版里的mid是l+r+1 >> 1还是l+r >> 1

最后循环的结果是l==r,要不找到了要不没找到

p.s.本来想找到第一个target之后遍历找一下第一个不是target的数, 超时了。。。

#include<iostream>
#include<algorithm>
using namespace std;
int main(){
    int n,q;
    cin>>n>>q;
    vector<int>vec(n);
    for(int i = 0;i<n;i++){
        cin>>vec[i];
    }
    int k;
    for(int i = 0;i<q;i++){
        cin>>k;//如何处理==的情况
        int l = 0;
        int r = n-1;
        int mid;
        while(l<r){//l<r
            mid = (l+r) >>1;
            if(vec[mid] >= k){//>=or> 1,3,3,3,,3
                r = mid;
            }else{
                l = mid+1;
            }
            
        }
        if(vec[l]!=k){
            cout<<"-1 -1"<<endl;//找的是第一个满足x的值
        }else{
            cout<<l<<" ";//while结束时l==r
            // while(vec[l]==k){
            //     l++;
            // }//有问题,这样就都加1了
            // l--;
            // cout<<l<<endl;
            //O(n)
            r = n-1;
            while(l<r){
                int mid = l+r+1 >> 1;
                if(vec[mid]<=k) l = mid;
                else{//
                    r =mid-1;
                }
            }
            cout<<l<<endl;
        }
        
        
    }
}

 同leetcode,问题就是nums[mid] == target时,到底归于哪一类

class Solution {
public:
    vector<int> searchRange(vector<int>& nums, int target) {
        int l = 0;
        int r = nums.size()-1;
        int mid;
        if(nums.size() == 0){
            return{-1,-1};
        }
        vector<int>vec(2);
        while(l<r){
            mid  = (l+r) >> 1;//开始位置
            if(nums[mid]>=target){
                r = mid;//mid-1-->mid??
            }else{
                l = mid+1;
            }

        }
        //l越界??
        if(nums[l] == target){
            vec[0] = l;
            r= nums.size()-1;
            while(l<r){
                mid = (l+r+1) >> 1;
                if(nums[mid]>target){
                    r = mid-1;//mid-1-->mid??
                }else{
                    l = mid;
                }
            }
            vec[1] = l;
        }else{
            vec[0] = -1;
            vec[1] = -1;
        }
        return vec;
    }
};

注: 把nums[mid]==target单独拎出来也通过了

class Solution {
public:
    vector<int> searchRange(vector<int>& nums, int target) {
        int l = 0;
        int r = nums.size()-1;
        int mid;
        if(nums.size() == 0){
            return{-1,-1};
        }
        vector<int>vec(2);
        while(l<r){
            mid  = (l+r) >> 1;//开始位置
            if(nums[mid]>target){
                r = mid-1;//mid-1-->mid??
            }else if(nums[mid]<target){
                l = mid+1;
            }else{
                r = mid;
            }

        }
        //l越界??
        if(nums[l] == target){
            vec[0] = l;
            r= nums.size()-1;
            while(l<r){
                mid = (l+r+1) >> 1;
                if(nums[mid]>target){
                    r = mid-1;//mid-1-->mid??
                }else if(nums[mid]<target){
                    l = mid+1;
                }else{
                    l = mid;
                }
            }
            vec[1] = l;
        }else{
            vec[0] = -1;
            vec[1] = -1;
        }
        return vec;
    }
};

5.搜索旋转排序数组5/11【1.5h+】

33. 搜索旋转排序数组 - 力扣(LeetCode)

原来的想法是找到peak【数组中max的地方】,然后重置数组(改成升序的数组),之后二分

but,重置数组时间复杂度是O(n)

问题:关于找peak,比如【4,5,6,7,8,0,1,2】我要找的是8这个位置

现在不太能理解:用nums[mid]和nums[mid+1]比较的这种if(check)函数?????

class Solution {
public:
    int find(vector<int>&nums){
        //复原数组需要O(n)空间 hhhhhhhhhh
        // if(l == r){
        //     return 0;
        // }
        // int i;int j;
        // int mid = (l+r+1)>>1;
        // if(mid == nums.size()-1){
        //     return 0;
        // }
        // if(nums[mid]>nums[mid+1]){
        //     return mid;
        // }else{
        //     i = find(nums,l,mid-1,target);
        //     j = find(nums,mid+1,r,target);
        //     //怀疑返回的值不太对
        // }
        // if(i!=0 || j!=0){
        //     return max(i,j);
        // }else{
        //     return 0;
        // }
        int l = 0;int r  = nums.size()-1;
        int max = nums[r];
        int mid;
        while(l<r){
            mid = (l+r+1)>>1;
            if(nums[mid]>max){//>=or>e.g.[3,1]
                l = mid;
            }else{
                r = mid-1;
            }
        }
        // if()
        return l;
    }
    int search(vector<int>& nums, int target) {
        //[nums[k], nums[k+1], ..., nums[n-1],         nums[0], nums[1], ..., nums[k-1]]
        //旋转后 的数组 nums 和一个整数 target
        //先复原?也不太对诶
        int peak = find(nums);
        cout<<peak<<endl;
        int l;int r;
        if(peak == nums.size()-1){
            l = 0;
            r = nums.size()-1;
        }else if(nums[0]<=target && nums[peak]>=target){
            l = 0;r = peak;

        }else{
            l = peak+  1;
            r = nums.size()-1;
        }
        int mid;
        while(l<r){
            mid = (l+r+1)>>1;
            if(nums[mid] > target){
                r = mid-1;
            }else if(nums[mid]<target){
                l = mid+1;
            }else{
                return mid;
            }
        }
        if(l==nums.size()){
            return -1;
        }
        if(nums[l] == target){
            return l;
        }else{
            return -1;
        }
        
    }
};

上面这个peak判断如果==nums.size( )-1其实有问题

emmmm

如果他是完全升序的数组,其实会收敛于0

但如果判断peak==0来看是不是完全升序的数组也有问题

比如【3,1】

其实peak输出是0,但不是完全升序的数组

所以关键在于nums[peak]和nums[nums.size()-1]的大小比较

改为:

class Solution {
public:
    int find(vector<int>&nums){
        //复原数组需要O(n)空间 hhhhhhhhhh
        // if(l == r){
        //     return 0;
        // }
        // int i;int j;
        // int mid = (l+r+1)>>1;
        // if(mid == nums.size()-1){
        //     return 0;
        // }
        // if(nums[mid]>nums[mid+1]){
        //     return mid;
        // }else{
        //     i = find(nums,l,mid-1,target);
        //     j = find(nums,mid+1,r,target);
        //     //怀疑返回的值不太对
        // }
        // if(i!=0 || j!=0){
        //     return max(i,j);
        // }else{
        //     return 0;
        // }
        int l = 0;int r  = nums.size()-1;
        int max = nums[r];
        int mid;
        while(l<r){
            mid = (l+r+1)>>1;
            if(nums[mid]>max){//>=or>e.g.[3,1]
                l = mid;
            }else{
                r = mid-1;
            }
        }
        // if()
        return l;
    }
    int search(vector<int>& nums, int target) {
        //[nums[k], nums[k+1], ..., nums[n-1],         nums[0], nums[1], ..., nums[k-1]]
        //旋转后 的数组 nums 和一个整数 target
        //先复原?也不太对诶
        int peak = find(nums);
        cout<<peak<<endl;
        int l;int r;
        if(nums[peak] < nums[nums.size()-1]){
            l = 0;
            r = nums.size()-1;
        }else if(nums[0]<=target && nums[peak]>=target){
            l = 0;r = peak;

        }else{
            l = peak+  1;
            r = nums.size()-1;
        }
        int mid;
        while(l<r){
            mid = (l+r+1)>>1;
            if(nums[mid] > target){
                r = mid-1;
            }else if(nums[mid]<target){
                l = mid+1;
            }else{
                return mid;
            }
        }
        if(l==nums.size()){
            return -1;
        }
        if(nums[l] == target){
            return l;
        }else{
            return -1;
        }
        
    }
};

法二:nums[mid]和nums[mid+1],如果不是峰值就左右搜索:

p.s.体会如果要搜两边,用递归函数怎么写

class Solution {
public:
    int findPeakRecursive(vector<int>& nums, int l, int r) {
        // 终止条件:区间无效或只剩一个元素
        if (l >= r) return -1;

        int mid = l + (r - l) / 2;

        // 关键检查:mid+1是否越界?
        if (mid + 1 > nums.size() - 1) {
            return -1; // 越界说明无法比较,放弃此分支
        }

        if (nums[mid] > nums[mid + 1]) {
            return mid; // 找到峰值
        } else {
            // 先搜索右侧
            int right_peak = findPeakRecursive(nums, mid + 1, r);
            if (right_peak != -1) return right_peak;

            // 右侧未找到,搜索左侧
            int left_peak = findPeakRecursive(nums, l, mid);
            return left_peak;
        }
    }

    int find(vector<int>& nums) {
        if (nums.empty()) return -1;
        int peak = findPeakRecursive(nums, 0, nums.size() - 1);

        // 处理完全升序数组(如 [1,2,3,4])
        if (peak == -1) {
            return nums.size() - 1; // 最后一个元素是峰值
        }
        return peak;
    }
        // int l = 0;int r  = nums.size()-1;
        // int max = nums[r];
        // int mid;
        // while(l<r){
        //     mid = (l+r+1)>>1;
        //     if(nums[mid]>max){//>=or>e.g.[3,1]
        //         l = mid;
        //     }else{
        //         r = mid-1;
        //     }
        // }
        // // if()
        // return l;
    // }
    int search(vector<int>& nums, int target) {
        //[nums[k], nums[k+1], ..., nums[n-1],         nums[0], nums[1], ..., nums[k-1]]
        //旋转后 的数组 nums 和一个整数 target
        //先复原?也不太对诶
        int peak = find(nums);
        cout<<peak<<endl;
        int l;int r;
        if(peak == nums.size()-1){
            l = 0;
            r = nums.size()-1;
        }else if(nums[0]<=target && nums[peak]>=target){
            l = 0;r = peak;

        }else{
            l = peak+  1;
            r = nums.size()-1;
        }
        int mid;
        while(l<r){
            mid = (l+r+1)>>1;
            if(nums[mid] > target){
                r = mid-1;
            }else if(nums[mid]<target){
                l = mid+1;
            }else{
                return mid;
            }
        }
        if(l==nums.size()){
            return -1;
        }
        if(nums[l] == target){
            return l;
        }else{
            return -1;
        }
        
    }
};

6.寻找旋转排序数组中的min5/12【18min】

153. 寻找旋转排序数组中的最小值 - 力扣(LeetCode)

昨天好像有很多迷惑的点,emmmm,忘记了。。。。

感觉:就像在碰运气,按着测试用例改代码

有几个问题

1.涉及(l+r+1)>>1还是要先判断if(nums.size()==1),要不然会越界

2.关于这个思路找峰值点,完全升序peak收敛于0,但不能用peak==0判断是否是完全升序的数组e.g.【3,1】,他这个峰值刚好是0,应该用nums[0]和max比较

class Solution {
public:
    int findMin(vector<int>& nums) {
        if(nums.size()==1){
            return nums[0];
        }
        //找到峰值点的下一个数
        int l = 0;int r = nums.size()-1;int mid;
        int max = nums[r];
        while(l<r){
            mid = (l+r+1)>>1;//[1]
            if(nums[mid]<= max){
                r = mid - 1;
            }else{
                l = mid;//如果mid就是那个peak
            }
        }
        cout<<l;
        if(nums[0]<max){
            return nums[0];
        }else{
            return nums[l+1];
        }
    }
};

7.寻找两个有序数组的中位数【没思路】5/12、5/13【总约为3H】

边界情况

突然感觉很久很久之前貌似做过

思路【看leetcode题解视频】

边界情况:

b/d不存在,即划分的线在数组末尾

迷茫了,困惑了。。。。。【54:39】 

有一个问题就是对于check中==的处理,一定是某种条件的逆否吗????

==>5/13如果return的逻辑太复杂,可以不写在while里,这样的话就是while(){if(check){left = mid+1}.....}这种,一般都是一个取反的区间,最后收敛在l==r那里【y总的模版】

看着测试用例打补丁,打不动了。。。。

混乱版本:

class Solution {
public:
    double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {
        // 两个大小分别为 m 和 n 的正序(从小到大)数组 nums1 和 nums2。请你找出并返回这两个正序数组的 中位数 。
        //合并需要O(m+n)
        //一个很严重的问题,我想的是a和c是作为分界线前面的元素下标,但是给的a的范围是0,nums1.size()-1,应该是-1,nums.size()-1
        if(nums1.size()>nums2.size()){
            swap(nums1,nums2);
        }
        int m = nums1.size();
        int n = nums2.size();
        cout<<m+n;
        int a;int b;int c;int d;
        int half = (m+n+1)/2;
        int l = -1;int r = nums1.size()-1;
        int mid;
        if(n ==1){//如果a=-1,且c==0,则c-1越界
            return nums2[0];
        }
        while(l<r){
            mid = (l+r+1)>>1;
            a = mid;
            b = mid+1;
            c= half-a-2;//下标和元素个数差了1
            d = c+1;
            // if(b!=nums1.size()-1){
                
                if( (a!=-1 && nums1[a]<=nums2[d]) || (a==-1 && nums1[b]>=nums2[c]) ){
                    if((m+n)%2 == 0){//偶数
                        return (max(a == -1 ? nums1[c-1] : nums1[a],nums2[c]) + min(nums1[b],nums2[d]))/2.0;//??
                    }else{
                        return max(a == -1 ? nums1[c-1] : nums1[a],nums2[c]);
                    }
                    
                    // r = mid;
                }else if((a!=-1 && nums1[a] > nums2[d]) || (a==-1 && nums1[b]<nums2[c])){
                    l = mid-1;
                }else{
                    r = mid;//mid??
                }
                
            // }else{
            //     if(nums1[a]<=nums2[d]){
            //         return max(nums1[a],nums2[c]);
            //     }
            //     else{
            //         r = mid-1;
            //     }

            // }
            
        }
        return -1;
    }
};

如果return的逻辑太复杂,可以不写在while里

妙点:

1.确保nums1更短,减少情况讨论

2.mid找的时候定义为分界线后面的那个元素下标,表示前面的元素个数,又因为(l+r+1)>>1,mid不会等于0【如果等于0,l==r==0,此时不满足while循环】,不需要关注mid-1是否越界

3.abcd是否会越界变成了越界就赋值max、min

最后直接判断奇数偶数,直接找max/min

class Solution {
public:
    double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {
        if(nums1.size()>nums2.size()){//确保nums2更长
            swap(nums1,nums2);
        }
        int m = nums1.size();
        int n = nums2.size();
        int half = (m+n+1)/2;
        int l = 0;int r = nums1.size();
        int mid;
        int c;
        while(l<r){//nums1不会出现
           mid = (l+r+1)>>1;//mid表示前面的元素个数,在分界线后
           c = half-mid;
           if(nums1[mid-1]>nums2[c]){
                r = mid-1;
           }else{
                l = mid;
           }
        }
        mid = (l+r+1)>>1; // 确保mid被正确初始化
        int a = mid-1;
        int b = mid;
        int c2 = half-b; // 修改变量名避免冲突
        int d = c2;
        int l1 = (a == -1 ? -1e9 : nums1[a]); // 修改条件为a == -1
        int l2 = (c2 == 0 ? -1e9 : nums2[c2-1]); // 修改索引和条件
        int r1 = (b == m ? 1e9 : nums1[b]);
        int r2 = (d == n ? 1e9 : nums2[d]);

        if((m+n)%2==0){//偶数
            return(max(l1,l2)+min(r1,r2))/2.0;
        }else{
            return max(l1,l2);
        }
    }
};

 p.s.另一种

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值