专题三:二分查找~
二分查找模板
注意:重点是二分查找的关键在于找到区间的二段性
一、二分查找
链接:704. 二分查找
public int search(int[] nums, int target) {int left = 0,right = nums.length - 1;while (left <= right) {int mid = left + (right - left) / 2;if(nums[mid] > target) right = mid - 1;else if (nums[mid] < target) left = mid + 1;else return mid;}return -1;}
二、在排序数组中查找元素的第一个和最后一个位置
链接: 34. 在排序数组中查找元素的第一个和最后一个位置
public int[] searchRange(int[] nums, int target) {int[] ret = new int[2];ret[0] = ret[1] = -1;if (nums.length == 0) return ret;//查找左端点int left = 0,right = nums.length - 1;while (left < right) {int mid = left + (right - left) / 2;if (nums[mid] < target) left = mid + 1;else right = mid;}if (nums[left] != target) return ret;else ret[0] = left;//查找右端点left = 0;right = nums.length - 1;while (left < right) {int mid = left + (right - left + 1) / 2;if (nums[mid] <= target) left = mid;else right = mid - 1;}ret[1] = right;return ret;}
三、x 的平方根
链接: 69. x 的平方根
public int mySqrt(int x) {if(x < 1) return 0;long left = 1,right = x;while (left < right) {long mid = left + (right -left + 1) / 2;if (mid * mid <= x) left = mid;else right = mid -1;}return (int)right;}
四、搜索插入位置
链接: 35. 搜索插入位置
public int searchInsert(int[] nums, int target) {int left = 0,right = nums.length - 1;while (left < right) {int mid = left + (right - left + 1) / 2;if (nums[mid] <= target) left = mid;else right = mid - 1; }if (nums[left] < target) return left + 1;return left;}
五、山脉数组的峰顶索引
链接: LCR 069. 山脉数组的峰顶索引
public int peakIndexInMountainArray(int[] arr) {int left = 1,right = arr.length - 2;while (left < right) {int mid = left + (right - left + 1) / 2;if (arr[mid] > arr[mid - 1]) left = mid;else right = mid - 1;}return left;}
六、寻找峰值
链接: 162. 寻找峰值
public int findPeakElement(int[] nums) {int left = 0,right = nums.length - 1;while (left < right) {int mid = left + (right - left + 1) / 2;if (nums[mid] < nums[mid- 1]) right = mid - 1;else left = mid;}return left;}
七、寻找旋转排序数组中的最小值
链接: 153. 寻找旋转排序数组中的最小值
public int findMin(int[] nums) {int left = 0,right = nums.length - 1,n = nums.length;while (left < right) {int mid = left + (right - left) /2;if (nums[mid] > nums[n - 1]) left = mid + 1;else right = mid;}return nums[left];}
八、点名
链接: LCR 173. 点名
1.二分查找(最优代码)
public int takeAttendance(int[] records) {int left = 0,right = records.length - 1;while (left < right) {int mid = left + (right - left) / 2;if (records[mid] == mid) left = mid + 1;else right = mid;}return records[left] == left ? left + 1 : left;}
2.哈希表
public int takeAttendance1(int[] records) {int[] hash = new int[records.length + 1];for (int x : records) {hash[x]++;}int i = 0;for (;i < hash.length;i++) {if (hash[i] == 0)return i;}return -1;}
3.位运算
public int takeAttendance2(int[] records) {int ret = records.length;for (int i = 0;i < records.length;i++) {ret ^= records[i] ^ i;}return ret;}
4.数学求和
public int takeAttendance3(int[] records) {int sum = 0;for (int i = 0;i <= records.length;i++){sum += i;}for (int x : records) {sum -= x;}return sum;}
5.暴力求解
public int takeAttendance(int[] records) {int ret = records.length;for (int i = 0; i < ret; i++) {if (records[i] != i)return i;}return ret;}
本期内容到此为止,喜欢的话请点个赞,谢谢观看!!!