1、二分法
二分法,需要注意mid 的取值,以及while中的等于号
1.1、搜索查找位置
public int searchInsert(int[] nums, int target) {int low = 0, high = nums.length - 1;int mid;while (low <= high) {mid = low + (high-low)/2;// System.out.println("a -- mid:" +(low+ (low + high) / 2));// System.out.println("b -- mid:" + (mid));if (nums[mid]>=target) high = mid - 1;else low = mid + 1;}return low;}
在上述中的数组中如果存在数字会直接返回结果,在while中可以不加等于号,当数组中不存在时,最后一次循环结果low = right ,且 mid = low 因此也可改造成下列程序:
//简单的二分查找if (nums == null || nums.length == 0) {return 0;}//小知识点: java数组的最大长度为int的最大值int left = 0;int right = nums.length - 1;while (left < right) {int mid = (left + right) / 2;if (target == nums[mid]) {return mid;} else if (target < nums[mid]) {right = mid - 1;} else {left = mid + 1;}}//此时left = rightreturn target <= nums[left] ? left : left + 1;}
1.2、搜索二维矩阵
常规方法:分两次,分别是对列和行分别用二分法查找
public boolean searchMatrix(int[][] matrix, int target) {int m = matrix.length, n = matrix[0].length;boolean res = false;int low = -1,high = m-1; //左开右闭的原则while (low < high) {int mid = low + (high - low+1) / 2;if (matrix[mid][0]<=target) low= mid;else high=mid-1;}if(low<0) return false;System.out.println(low);int left = 0, right = n - 1;while (left <= right) {int mid = left + (right - left) / 2;if (matrix[low][mid]<target) left = mid + 1;else if (matrix[low][mid]>target) right = mid - 1;else return true;}return res;}
一次拼接法:根据数组性质,将每一行的末尾与下一行进行拼接 并且将下标映射到原矩阵的行与列上
class Solution {public boolean searchMatrix(int[][] matrix, int target) {int m = matrix.length, n = matrix[0].length;int low = 0, high = m * n - 1;while (low <= high) {int mid = (high - low) / 2 + low;int x = matrix[mid / n][mid % n]; //下标映射if (x < target) {low = mid + 1;} else if (x > target) {high = mid - 1;} else {return true;}}return false;}}
1.3、在排序数组中查找元素的第一个和最后一个位置
可以直接套用二分法查找模板,当找到目标元素时,进行左右遍历,找到边界
public int[] searchRange(int[] nums, int target) {int[] res = new int[]{-1, -1};int left = 0, right = nums.length - 1;while (left <= right) {int mid = (left + right) / 2;if (target == nums[mid]) {left = mid;// System.out.println(mid);while (mid>=0 && nums[mid] == target) {mid--;}res[0] = mid + 1;while (left<nums.length && nums[left] == target) {left++;}res[1] = left - 1;return res;} else if (target < nums[mid]) {right = mid - 1;} else {left = mid + 1;}}return res;}
左右分别求解
···java
