本文共 4079 字,大约阅读时间需要 13 分钟。
y总的两个模板: (下面两个模板只适用于在区间内存在要寻找的值时才适用,当然不存在也可以用只是要对模板修改)
模板1//更新方式为l=mid+1,r=midint binarySearch(int l,int r){ int mid; while(l
模板2
//更新方式为l=mid,r=mid-1int binarySearch(int l,int r){ int mid; while(l
注意要用long最后强转一下,因为用int尤其在mid*mid那个地方绝对会越界 下面套用两个模板,其中第一个成功通过,第二个失败,具体原因分析如注释:
模板2
class Solution { //该种写法最后返回的要么是mid-1,要么是mid,而条件是mid*mid>x,假如mid*mid>x,返回mid-1,为正确值,如果mid*mid<=x,返回mid也为正确值 public int mySqrt(int x) { long l=0,r=x; long mid; while(lx) r=mid-1; else l=mid; } return (int)l; }}
题目描述:
实现 int sqrt(int x) 函数。
计算并返回 x 的平方根,其中 x 是非负整数。 由于返回类型是整数,结果只保留整数的部分,小数部分将被舍去。 示例 1: 输入: 4 输出: 2 示例 2: 输入: 8 输出: 2 说明: 8 的平方根是 2.82842…, 由于返回类型是整数,小数部分将被舍去。
模板1
class Solution {//该种写法最后返回的要么是mid+1,要么是mid,而条件是mid*mid<=x,假如mid*mid<=x,返回mid+1,为比正确值大一,如果mid*mid>x,返回mid也为比正确值大一 public int mySqrt(int x) { long l=0,r=x; long mid; while(l
下面对模板1进行改进(提交通过)
class Solution{public int mySqrt(int x) { long l=0,r=x; //0与1要单独讨论 if(r==0) return 0; if(r==1) return 1; long mid; while(l
总结:千万不要为了用哪一个模板而改模板,而应该选择适用的的那一个
题目描述:
给定一个按照升序排列的整数数组 nums,和一个目标值 target。找出给定目标值在数组中的开始位置和结束位置。你的算法时间复杂度必须是 O(log n) 级别。如果数组中不存在目标值,返回 [-1, -1]。示例 1:输入: nums = [5,7,7,8,8,10], target = 8输出: [3,4]示例 2:输入: nums = [5,7,7,8,8,10], target = 6输出: [-1,-1]
class Solution { public int[] searchRange(int[] nums, int target) { int[] a=new int[2]; a[0]=a[1]=-1; if(nums.length==0) return a; int l=0,r=nums.length-1; int mid; while(l=target)//大于等于那么此时第一个target必然在mid左边或等于mid r=mid; else l=mid+1; } a[0]=l; return a; }}
题目描述:
编写一个高效的算法来判断 m x n 矩阵中,是否存在一个目标值。该矩阵具有如下特性:每行中的整数从左到右按升序排列。每行的第一个整数大于前一行的最后一个整数。示例 1:输入:matrix = [ [1, 3, 5, 7], [10, 11, 16, 20], [23, 30, 34, 50]]target = 3输出: true示例 2:输入:matrix = [ [1, 3, 5, 7], [10, 11, 16, 20], [23, 30, 34, 50]]target = 13输出: false
class Solution { public boolean searchMatrix(int[][] matrix, int target) { int row=matrix.length; if(row==0) return false; int col=matrix[0].length; if(col==0) return false; int i,j; if(row==0) { return false; } int l=0,r =row*col-1; int mid ; while(l=target) r=mid; else l=mid+1; } if(((l+r)/2+1)%col==0){ i=((l+r)/2+1)/col-1; j=col-1; } else { i=((l+r)/2+1)/col; j=((l+r)/2+1)%col-1; } if(matrix[i][j]!=target) return false; else return true; }}
升级版:
题目描述:
假设按照升序排序的数组在预先未知的某个点上进行了旋转。( 例如,数组 [0,1,2,4,5,6,7] 可能变为 [4,5,6,7,0,1,2] )。请找出其中最小的元素。你可以假设数组中不存在重复元素。示例 1:输入: [3,4,5,1,2]输出: 1示例 2:输入: [4,5,6,7,0,1,2]输出: 0
class Solution { //使用二分的思想来解决问题 public int findMin(int[] nums) { int mid; int left = 0; int right = nums.length-1; if(nums[0]>1; if(nums[mid]
题目描述:
峰值元素是指其值大于左右相邻值的元素。给定一个输入数组 nums,其中 nums[i] ≠ nums[i+1],找到峰值元素并返回其索引。数组可能包含多个峰值,在这种情况下,返回任何一个峰值所在位置即可。你可以假设 nums[-1] = nums[n] = -∞。示例 1:输入: nums = [1,2,3,1]输出: 2解释: 3 是峰值元素,你的函数应该返回其索引 2。示例 2:输入: nums = [1,2,1,3,5,6,4]输出: 1 或 5 解释: 你的函数可以返回索引 1,其峰值元素为 2; 或者返回索引 5, 其峰值元素为 6。 说明:你的解法应该是 O(logN) 时间复杂度的。
class Solution { public int findPeakElement(int[] nums) { if(nums.length==1) return 0; if(nums[nums.length-1]>nums[nums.length-2]) return nums.length-1; int left = 0; int right = nums.length-1; int mid; while(left>1; if(mid<=nums.length-2&&nums[mid]>nums[mid+1]) right=mid; else left = mid+1; } return left; }}
这个问题的升级版为二维矩阵峰值的查找,如果你觉得本问题难度不大,可以参考这篇文章提升自己:
转载地址:http://tplzi.baihongyu.com/