Go语言数据结构和算法(二十七)二分搜索

29 阅读2分钟

二分搜索是一种在有序数组使用的算法.它通过重复将搜索间隔一分为二进行搜索.二

分搜素算法的思想是利用数组排序的信息.将事件复杂度降低到O(logn).

1.步骤:

1).将整个数组的中间元素作为搜索键并从此处开始搜索.

2).如果搜索键的值等于元素的值.则返回搜索键的索引.

3).如果搜索键的值小于区间中间的项.则将区间缩小到下半部分.否则将其缩小到上半部分.

4).从步骤2开始反复查询.直到值或区间为空.

2.场景:

大型数据集:二分搜索算法对于大型数据集非常有效.因为其他算法的开销对性能影响很大.

精确匹配:二分搜索算法在搜索精确匹配时很有用.因为它会找到目标元素集中第一次出现的位置.

3.实现:

3.1方法:

package data

import "sort"

func BinarySearch(need int, nums []int) bool {
	low := 0
	sort.Ints(nums)
	high := len(nums) - 1
	for low < high {
		mid := (low + high) / 2
		if nums[mid] > need {
			high = mid - 1
		} else {
			low = mid + 1
		}
	}
	if nums[low] != need || low == len(nums) {
		return false
	}
	return true
}

3.2main方法:

func main() {
	array := []int{1, 2, 9, 20, 31, 45, 63, 70, 100}
	search1 := data.BinarySearch(1, array)
	search2 := data.BinarySearch(101, array)
	fmt.Println(search1, search2)
}

4.实战:

给定一个正整数数组array.其中array[i]描述索引i的权重.编写一个函数.它随机选择与其权重成比例的索引.

4.1方法:

func NewSolution(array []int) Solution {
	values := []int{}
	current := 0
	for _, v := range array {
		current += v
		values = append(values, current)
	}
	rand.Seed(time.Now().UnixNano())
	return Solution{
		Values:   values,
		MaxValue: current,
	}
}

func (s *Solution) PickIndex() int {
	num := rand.Intn(s.MaxValue)
	return findGreater(s.Values, num)
}

func findGreater(values []int, num int) int {
	l, r := 0, len(values)-1
	for l < r {
		mid := (l + r) >> 1
		if values[mid] > num {
			r = mid - 1
		} else {
			l = mid + 1
		}
	}
	return l
}

4.2main方法:

	array := []int{1, 2, 9, 20, 31, 45, 63, 70, 100}
	res := data.NewSolution(array)
	fmt.Println(res.MaxValue)
	fmt.Println(res.Values)
	index := res.PickIndex()
	fmt.Println(index)
}

5.实战:

给定一个按升序排列的整数数组array和两个整数k和x.请找到数组中与x最接近的k个元素.结果按升序排序.如果存在平局.则始终首选较小的元素.

5.1方法:

func SearchClosestElements(array []int, k int, x int) []int {
	low, high := 0, len(array)-k
	for low < high {
		mid := (low + high) >> 1
		if x-array[mid] > array[mid+k]-x {
			low = mid + 1
		} else {
			high = mid
		}
	}
	return array[low : low+k]
}

5.2mian方法:

func main() {
	array := []int{1, 2, 4, 5, 6, 8, 99, 251, 320}
	elements := data.SearchClosestElements(array, 6, 1)
	fmt.Println(elements)
}

终是庄周梦中蝶.



如果大家喜欢我的分享的话.可以关注我的微信公众号

念何架构之路