在Go(Golang)中查找排序数组中目标元素的第一个和最后一个位置的方法

248 阅读1分钟

概述

我们的目标是找到一个元素在排序数组中的第一个和最后一个位置。

实验结果

Input: [1, 2, 2, 5]
Target: 2
Output: [1, 2]

Input: [1, 2, 5]
Target: 2
Output: [1, 1]

Input: []
Target: 1
Output: [-1,-1]

策略是

  • 在数组中进行二进制搜索,找到左边的索引。

  • 然后在数组中再做一次二进制搜索,找到右边的索引。

程序

以下是相同的程序

package main

import "fmt"

func main() {
	output := searchRange([]int{1, 2, 2, 5}, 2)
	fmt.Println(output)

	output = searchRange([]int{1, 2, 5}, 2)
	fmt.Println(output)

	output = searchRange([]int{}, 1)
	fmt.Println(output)
}

func searchRange(nums []int, target int) []int {

	output := make([]int, 2)
	output[0] = findLeftPivot(nums, 0, len(nums)-1, target, len(nums))

	output[1] = findRightPivot(nums, 0, len(nums)-1, target, len(nums))

	return output
}

func findLeftPivot(nums []int, start, end, target, len int) int {
	if start > end {
		return -1
	}

	if start == end && nums[start] == target {
		return start
	}

	mid := (start + end) / 2

	if (mid == 0 || nums[mid-1] < nums[mid]) && nums[mid] == target {
		return mid
	}

	if target <= nums[mid] {
		return findLeftPivot(nums, start, mid-1, target, len)
	}

	return findLeftPivot(nums, mid+1, end, target, len)

}

func findRightPivot(nums []int, start, end, target, len int) int {
	if start > end {
		return -1
	}

	if start == end && nums[start] == target {
		return start

	}

	mid := (start + end) / 2

	if mid+1 <= end && nums[mid] == target && nums[mid] < nums[mid+1] {
		return mid
	}

	if (mid == len-1 || nums[mid] < nums[mid+1]) && nums[mid] == target {
		return mid - 1
	}

	if target >= nums[mid] {
		return findRightPivot(nums, mid+1, end, target, len)
	}

	return findRightPivot(nums, start, mid-1, target, len)

}

输出

[1 2]
[1 1]
[-1 -1]