leetcode Search for a Range

本文介绍了一个使用二分查找算法解决的问题:在一个升序排列的整数数组中找到目标值的起始和结束位置。该算法的时间复杂度为 O(log n),符合题目要求。通过多次二分查找实现,并提供了一个 Go 语言的实现示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Given an array of integers sorted in ascending order, find the starting and ending position of a given target value.

Your algorithm's runtime complexity must be in the order of O(log n).

If the target is not found in the array, return [-1, -1].

For example,
Given [5, 7, 7, 8, 8, 10] and target value 8,
return [3, 4].

题目很简单,就是多次二分查找嘛,但是写起来要稍微注意一点细节,上我的代码

package main

import (
	"fmt"
)

const (
	NOT_FOUND = -1
)

// 二分查找
func find_num(arr []int, num int, left_index int, right_index int) int {
	mid_index := (left_index + right_index) / 2
	for left_index < right_index-1 {
		if num < arr[mid_index] {
			right_index = mid_index
			mid_index = (left_index + right_index) / 2
		} else if num > arr[mid_index] {
			left_index = mid_index
			mid_index = (left_index + right_index) / 2
		} else {
			return mid_index
		}
	}

	if num == arr[right_index] {
		return right_index
	} else if num == arr[left_index] {
		return left_index
	}

	return NOT_FOUND
}

func start_end_pos(arr []int, num int) (int, int) {
	length := len(arr)
	left_index := 0
	right_index := length - 1

	one_index := find_num(arr, num, left_index, right_index)

	start_index := one_index
	end_index := one_index

	if one_index > left_index {
		pos := find_num(arr, num, left_index, one_index-1)
		if pos != NOT_FOUND {
			start_index = pos
		}
	}
	if one_index+1 < right_index {
		pos := find_num(arr, num, one_index+1, right_index)
		if pos != NOT_FOUND {
			end_index = pos
		}
	}

	left_flag := true
	right_flag := true

	for left_flag || right_flag {
		if start_index > left_index && left_flag {

			//裁剪
			if num != arr[start_index-1] {
				left_flag = false
				goto right
			}
			//查找
			pos := find_num(arr, num, left_index, start_index-1)

			if pos == NOT_FOUND || start_index == pos {
				left_flag = false
			} else {
				start_index = pos
			}
		}
	right:
		if end_index+1 < right_index && right_flag {

			//裁剪
			if num != arr[end_index+1] {
				right_flag = false
				continue
			}
			//查找
			pos := find_num(arr, num, end_index+1, right_index)

			if pos == NOT_FOUND || end_index == pos {
				right_flag = false
			} else {
				end_index = pos
			}
		}

	}

	return start_index, end_index
}

func main() {
	arr := []int{3, 4, 5, 5, 5, 5, 23, 56}
	start, end := start_end_pos(arr, 5)
	fmt.Printf("[%d,%d]", start, end)
}

输出结果:

[2,5]

 

转载于:https://my.oschina.net/yang1992/blog/836786

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值