NOTE

在转动过的有序数组中寻找目标值

在转动过的有序数组中寻找目标值 的 LeetCode 解题笔记。

Data Structures & Algorithms创建于 更新于 约 1 分钟读完historical

这是历史学习笔记,可能存在过时或不完整的理解。

1. 题目描述

给出一个转动过的有序数组,你事先不知道该数组转动了多少 (例如,0 1 2 4 5 6 7可能变为4 5 6 7 0 1 2). 在数组中搜索给出的目标值,如果能在数组中找到,返回它的索引,否则返回-1。 假设数组中不存在重复项。

2. 思路

对比旋转数组的最小数字.md,一个是找最小值,一个是找目标值

3. 实现

3.1. 二分

func search(A []int, target int) int {
	if len(A) == 0 {
		return -1
	}

	left := 0
	right := len(A) - 1
	for left <= right {
		mid := (left + right) / 2
		if A[mid] == target {
			return mid
		} else if A[mid] >= A[left] {
			//左侧有序
			if A[mid] > target && A[left] <= target {
				right = mid - 1
			} else {
				left = mid + 1
			}
		} else {
			//右侧有序
			if A[mid] < target && A[right] >= target {
				left = mid + 1
			} else {
				right = mid - 1
			}

		}
	}
	return -1
}

3.2. 极值

func search(nums []int, target int) int {
    minIndex := findMin(nums)
    ldx := bSearch(nums, 0, minIndex-1, target)
    if ldx != -1 {
        return ldx
    }
    rdx := bSearch(nums, minIndex, len(nums)-1, target)
    return rdx
}

func bSearch(nums[]int, left,right,target int) int {
    for left <= right {
        mid := left + (right-left) / 2
        if nums[mid] == target {
            return mid
        }else if nums[mid] > target {
            right = mid -1
        }else {
            left = mid +1
        }
    }
    return -1
}

func findMin(nums []int) int {
    left := 0
    right := len(nums)-1
    for left < right {
        mid := left + (right-left)/2
        if nums[mid] > nums[right] {
            left = mid + 1
        }else {
            right = mid
        }
    }
    return left
}
 
func search(nums []int, target int) int {
    minIdx := findMin(nums)
    idx := bSearch(nums, 0, minIdx-1,target)
    if idx != -1 {return idx}
    idx = bSearch(nums, minIdx, len(nums)-1,target)
    if idx != -1 {return idx}
    return -1
}

func bSearch(nums []int, left, right, target int) int {
    for left <= right {
        mid := left + (right-left)>>1
        if nums[mid] == target {
            return mid
        } else if nums[mid] < target {
            left = mid+1
        } else {
            right = mid-1
        }
    }
    return -1
}

func findMin(nums []int) int {
    left := 0
    right := len(nums)-1
    for left < right {
        mid := left + (right-left)>>1
        if nums[mid] > nums[right] {
            left=mid+1
        }else {
            right=mid
        }
    }
    return left
}

4. 参考

讨论

使用 GitHub 账号参与讨论,评论会保存在 GitHub Issues 中。在 GitHub 查看