合并两个有序数组
- 给定两个有序整数数组 nums1 和 nums2,将 nums2 合并到 nums1 中,使得 num1 成为一个有序数组。
- 说明:
- 初始化 nums1 和 nums2 的元素数量分别为 m 和 n。
- 你可以假设 nums1 有足够的空间(空间大小大于或等于 m + n)来保存 nums2 中的元素。
- 示例:
- 输入:
- nums1 = [1,2,3,0,0,0], m = 3
- nums2 = [2,5,6], n = 3
- 输出: [1,2,2,3,5,6]
- 输入:
解
- 方法一: 尾插法
- 思路:
-
事实上使用头插法依旧是可以的,但是头插法需要把前nums1中的m个元数先copy出来,从而有m的空间复杂度,而使用尾插法,可以避免这个消耗,因为都是排个序的嘛,直接找最大的查到尾巴上就可以了
- 定义三个指针:
- 指向num1的尾巴:last_1
- 指向num2的尾巴:last_2
- 指向num1合并后数组的尾巴:last_m
- 从num1和num2中挑最大的加入到last_m上
- 然后将未插入完的加入进去
-
- Code
void merge(vector<int>& nums1, int m, vector<int>& nums2, int n) { int last_1=m-1, last_2=n-1, last_m=m+n-1; while(last_2 >= 0 && last_1>=0){ if(nums2[last_2] >= nums1[last_1]){ nums1[last_m--]=nums2[last_2--]; }else{ nums1[last_m--]=nums1[last_1--]; // nums1[last_m--]=nums2[last_2--]; } } while(last_2>=0){ nums1[last_m--]=nums2[last_2--]; } }
- 思路:
第一个错误的版本
- 你是产品经理,目前正在带领一个团队开发新的产品。不幸的是,你的产品的最新版本没有通过质量检测。由于每个版本都是基于之前的版本开发的,所以错误的版本之后的所有版本都是错的。
- 假设你有 n 个版本 [1, 2, …, n],你想找出导致之后所有版本出错的第一个错误的版本。
- 你可以通过调用 bool isBadVersion(version) 接口来判断版本号 version 是否在单元测试中出错。实现一个函数来查找第一个错误的版本。你应该尽量减少对调用 API 的次数。
- 示例:
- 给定 n = 5,并且 version = 4 是第一个错误的版本。
- 调用 isBadVersion(3) -> false
- 调用 isBadVersion(5) -> true
- 调用 isBadVersion(4) -> true
- 所以,4 是第一个错误的版本。
解
- 方法: 二分查找
- 思路:
- 定义双向指针:
- 左指针:
l
; 右指针:r
- 左指针:
- 逻辑:
int mid = l + floor((r-l)/2);
:注意这里之所以不是floor((l+r)/2)
是因为有可能l+r
会溢出- 边界更新:
- 序列:
1 2 3 4 5 6 7 8 9
F F F F T T T T T
isBadVersion(mid)==false;
的情况下mid=3
时候, 此时第一个T
只可能存在于mid
的右边(不可能为mid
)l=mid+1
isBadVersion(mid)==true;
的情况下mid=5
的时候,此时第一个T
只可能存在于mid
的左边(可能为mid
)r=mid
- 序列:
- Code
int midfind(int l, int r){ while(l<r){ //if(l==r){break;} int mid = l + floor((r-l)/2); if(isBadVersion(mid)==false){ l=mid+1; }else{ r=mid; } } if(l!=r){return -1;} return l; }
- 定义双向指针: