704:二分查找
给定一个 n 个元素有序的(升序)整型数组 nums 和一个目标值 target ,写一个函数搜索 nums 中的 target,如果目标值存在返回下标,否则返回 -1。
方法一:
数组查找我暴力查找的,
错误点:for语句规则;return 返回值(在for中写了两个if判断)程序最后没有把不满足条件的值返回
方法二:二分法
思考:
做题之前:因为是有序数组,想直接通过for or while 写循环,写循环条件的时候,发现没法往左和右递归。
题解后,原来是看二分法的中间位置是不是想要查找的值 nums[mid]==target
二分法知识总结:
1.二分法使用的前提条件,数组是有序数组,且数组中无重复元素
2.二分法边界条件:每次递归的二分法的区间
while(left < right) or while(left <= right) right=middle or right = middle-1
区间定义的是不变量,每次循环的不变量
区间定义:左闭右闭[left,right],这里区间定义是什么意思呢?就是right有没有在区间中存在,看程序的最初right的定义
while(left <= right) right = middle-1
二分法程序总结:
1.判断target是否在整个数组的范围内
2.定义其实左右边界left,right
3.while循环(mid决定left和right的值)
中间值mid定义->判断左右区间的移动方向(不移动:mid就是要查找的值;左移动:right=mid-1;右移:left=mid+1)
4.没找到返回-1
刷题总结:
二刷:
思路没有问题了,在大脑中想象如何二分的动图;
出错点,mid=l+(r-l)<<1
左移符号是">>",没有把(r-l)>>1 叫括号,使得程序不知道要运行进行左移
方法一:暴力遍历
class Solution {
public int search(int[] nums, int target) {
for(int i= 0 ;i < nums.length;i++){
if(nums[i]==target){
return i;
}
}
return -1;
}
}
方法二:二分法
class Solution{
public int search(int[] nums,int target){
if(target<nums[0] || target > nums[nums.length-1]){
return -1;
}
int left = 0;
int right = nums.length-1;
while(left <= right){
int mid = left +((right-left)>>1);
if(target = nums[mid])
return mid;
else if(target >nums[mid])
left=mid+1;
else if(target < nums[mid])
right =mid-1;
}
return -1;
}
}
2.二分法查找有序数组
一个长度为n-1的递增排序数组中的所有数字都是唯一的,并且每个数字都在范围0~n-1之内。在范围0~n-1内的n个数字中有且只有一个数字不在该数组中,请找出这个数字。
class Solution {
public int missingNumber(int[] nums) {
// if(nums.length==1 && nums[0]==0) return 1;
//二分法:利用i对应的下标就是对应的数组值
int l = 0;
int r = nums.length-1;
while(l<=r){//二分法是等号
int mid = (l+r)/2;//向下取整
if(nums[mid] ==mid ) {
l=mid+1;
}else{
r=mid-1;
}
}
return l;
}
}