二分查找
二分查找是一种比较基础的算法,思路类似于小游戏-猜出0-100的某个数字,适用于数组有序的情况。二分查找不一定会比暴力方法快,二者都是不稳定的,具体用时和数据有关系。
二分查找的思路很简单,但是在真正去写二分查找时,会发现他的边界条件很难把控。
例题:
704. 二分查找
给定一个 n
个元素有序的(升序)整型数组 nums
和一个目标值 target
,写一个函数搜索 nums
中的 target
,如果目标值存在返回下标,否则返回 -1
。
提示:
- 你可以假设
nums
中的所有元素是不重复的。
n
将在 [1, 10000]
之间。
nums
的每个元素都将在 [-9999, 9999]
之间。
示例 1:
1 2 3
| 输入: nums = [-1,0,3,5,9,12], target = 9 输出: 4 解释: 9 出现在 nums 中并且下标为 4
|
示例 2:
1 2 3
| 输入: nums = [-1,0,3,5,9,12], target = 2 输出: -1 解释: 2 不存在 nums 中因此返回 -1
|
分享一下个人的思路:
- 记录目前可能最大和最小可能值的位置min(初始 0)、max(初始 length-1)
- 取最中间的位置(max+min),与target进行比较
- 若小于target,则min = 现在的位置+1、若大于target,则max = 现在的位置-1
- 当前位置 =(max+min)/ 2,循环,直至找到target或者max<min
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| class Solution { public int search(int[] nums, int target) { int length = nums.length; int max = length-1; int min = 0; int p = (max+min)/2; while(min<=max){ if(nums[p] == target){ return p; } else if(nums[p]<target){ min = p+1; p = (min+max)/2; } else if(nums[p]>target){ max = p-1; p = (max+min)/2; } } return -1; } }
|
当然有些时候我们脑子不太清醒,可能想不清楚边界关系,那也没逝分享一个自己的小寄巧:记录一下这个值有没有被比较过(不推荐使用,属于是没办法的办法)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| class Solution { public int search(int[] nums, int target) { int length = nums.length; int[] search = new int[length]; int max = length; int min = 0; int p = length/2; while(true){ if(nums[p] == target){ return p; } else if(nums[p]<target&&search[p]==0){ search[p] = 1; min = p; p = (p+max)/2; } else if(nums[p]>target&&search[p]==0){ search[p] = 1; max = p; p = (p+min)/2; } else { return -1; } } } }
|