搜索插入位置(035)
- class Solution {
- public int searchInsert(int[] nums, int target) {
- int n = nums.length;
- int lef = -1;
- int rig = n;
- while(lef+1 < rig){
- int mid = (lef + rig) / 2;
- if (nums[mid] < target){
- lef = mid;
- }else rig = mid;
- }
- return rig;
- }
- }
复制代码 根本二分
搜索二维矩阵(074)
- class Solution {
- public boolean searchMatrix(int[][] matrix, int target) {
- int m = matrix.length;
- int n = matrix[0].length;
- int lef = -1;
- int rig = m*n;
- while (lef+1 < rig){
- int mid = (lef + rig) / 2;
- int x = matrix[mid/n][mid%n];
- if (x < target) lef = mid;
- else if (x > target) rig = mid;
- else return true;
- }
- return false;
- }
- }
复制代码 把每一个row 横向相连, 作二分
在排序数组中查找元素的第一个和最后一个位置(034)
- class Solution {
- public int[] searchRange(int[] nums, int target) {
-
- int start = searchLower(-1 ,nums, target);
- if (start == nums.length || nums[start] != target) return new int[]{-1,-1};
- int end = searchLower(start, nums, target+1) -1;
- return new int[] {start, end};
- }
- private int searchLower(int lef, int[] nums, int target){
- int rig = nums.length;
- while (lef + 1 < rig){
- int mid = (lef + rig) / 2;
- if (nums[mid] < target) lef = mid;
- else rig = mid;
- }
- return rig;
- }
- }
复制代码 通过两次二分 查找 target 和target+1的起始位置, 确定target的范围
搜索旋转排序数组(033)
- class Solution {
- public int search(int[] nums, int target) {
- int n = nums.length -1;
- int lef = -1;
- int rig = n;
- while (lef + 1< rig){
- int mid = (lef + rig) / 2;
- if (check(nums, target, mid)){ //target在mid右侧
- lef = mid;
- }else rig = mid;
- }
- return nums[rig] == target ? rig : -1;
- }
- private boolean check(int[] nums, int target, int idx){
- int x = nums[idx];
- int end = nums[nums.length-1];
- if (x < end){
- return x < target && target <= end; // mid在小端 且比target小
- }
- // mid在大端 且< target在小端 || target > mid >
- return x < target || target <= end;
- }
- }
复制代码 判断 mid 在 →
二分用来查找数据的拐点, 以作check()
寻找两个正序数组的中位数(004)
这题给我写晕厥了😣😣- class Solution {
- public int findMin(int[] nums) {
- int n = nums.length;
- int lef = -1;
- int rig = n;
- while (lef+1 < rig){
- int mid = (lef + rig) / 2;
- if(nums[mid] > nums[n-1]){ // 在右侧
- lef = mid;
- }else rig = mid;
- }
- return nums[rig];
- }
- }
复制代码 我们取两数组作为总数据集的小端, 作为总数据集的大端
💡假设在全落在第一组
从取出值放入
从取出值放入
直到全落在第二组
我们可以看到, 的sum是先变小, 再变大, 显然我们可以观察到拐点, 即为sum最小值,也是我们要找的数据集小端
接下来我们通过二分找拐点if(nums1[mid_nums1] - nums2[mid_nums2+1] |