思路 二分查找,也可以称作折半查找。
即在一个有序序列中,通过每次对中间位置元素的判断来逐步缩小查找范围。
Sqrt(x) 问题描述 给定一个非负整数,求它的开方,向下取整。
解题思路 这个问题比较简单,一个非负整数的开发必然是小于等于他本身的。
所以我们可以将[0,x]看做一个有序序列,用二分查找的思想确定结果
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 func mySqrt (x int ) int { if x <= 1 { return x } start := 0 end := x i := start + (end-start)/2 for ; i != start; i = start + (end-start)/2 { temp := i * i if temp == x { return i } if temp < x { start = i } if temp > x { end = i } } return i }
Find First and Last Position of Element in Sorted Array 问题描述 给定一个增序的整数数组和一个值,查找该值第一次和最后一次出现的位置。
解题思路 因为数组是增序的,那么目标值肯定是连续的,只需要先找到任意一个目标值的位置,
然后向两边遍历就能找到其第一次和最后一次出现的位置。
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 31 32 33 func searchRange (nums []int , target int ) []int { result := []int {-1 , -1 } size := len (nums) if size == 0 { return result } start := 0 end := size - 1 mid := start + (end-start)/2 for start < end && nums[mid] != target { if nums[mid] > target { end = mid - 1 } else { start = mid + 1 } mid = start + (end-start)/2 } if nums[mid] != target { return result } min, max := mid-1 , mid+1 for min >= start && nums[min] == target { min-- } for max <= end && nums[max] == target { max++ } result = []int {min + 1 , max - 1 } return result }
Search in Rotated Sorted Array II 问题描述 一个原本增序的数组被首尾相连后按某个位置断开(如 [1,2,2,3,4,5] → [2,3,4,5,1,2],在第
一位和第二位断开),我们称其为旋转数组。给定一个值,判断这个值是否存在于这个为旋转数组中。
解题思路 虽然数组不是整体有序,但是以断开点为准分为左右两个子集,都是各自增序的。只要在二分查找中判断
当前所在是左子集还是右子集就行。
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 31 32 33 34 35 36 37 38 39 40 41 42 43 44 func search (nums []int , target int ) bool { start := 0 end := len (nums) - 1 mid := start + (end - start)/2 for ;start < end; mid = start + (end - start)/2 { if target == nums[mid]{ return true } if nums[mid] == nums[start]{ start++ }else { if nums[mid] > nums[start]{ if target == nums[start]{ return true } if target < nums[mid] && target > nums[start]{ end = mid-1 }else { start = mid+1 } }else { if target == nums[end]{ return true } if target > nums[mid] && target < nums[end]{ start = mid+1 }else { end = mid-1 } } } } if target == nums[mid]{ return true } return false }
总结 二分查找很好理解,十分依赖集合有序这个点。但并不一定是整体有序,就如旋转数组一样。
所以在使用二分查找时,需要找出目标集合的有序性,依据其有序性做为二分查找的依据。