博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
二分刷题讲解
阅读量:3959 次
发布时间:2019-05-24

本文共 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

二.题目y总的讲解笔记

1.

注意要用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(l
x) 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

总结:千万不要为了用哪一个模板而改模板,而应该选择适用的的那一个

2.

题目描述:

给定一个按照升序排列的整数数组 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; }}

3.

题目描述:

编写一个高效的算法来判断 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; }}

升级版:

4.

题目描述:

假设按照升序排序的数组在预先未知的某个点上进行了旋转。( 例如,数组 [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]

5.

题目描述:

峰值元素是指其值大于左右相邻值的元素。给定一个输入数组 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/

你可能感兴趣的文章