首页 > 其他分享 >二分法应用——搜索旋转数组,以前一直在纠结a[0],a[-1],a[mid], target三者关系,其实最简单的还是使用2次二分,先找到旋转数组peak,然后用正常的二分搜索即可!

二分法应用——搜索旋转数组,以前一直在纠结a[0],a[-1],a[mid], target三者关系,其实最简单的还是使用2次二分,先找到旋转数组peak,然后用正常的二分搜索即可!

时间:2023-05-31 10:37:21浏览次数:56  
标签:二分 return target mid start 搜索 数组 integer

62 · 搜索旋转排序数组

 

 

描述

给定一个有序数组,但是数组以某个元素作为支点进行了旋转(比如,0 1 2 4 5 6 7 可能成为4 5 6 7 0 1 2)。给定一个目标值target进行搜索,如果在数组中找到目标值返回数组中的索引位置,否则返回-1。你可以假设数组中不存在重复的元素。

背完这套刷题模板,真的不一样!

样例

样例 1:

输入:

数组 = [4, 5, 1, 2, 3]
target = 1

输出:

2

解释:

1在数组中对应索引位置为2。

样例 2:

输入:

数组 = [4, 5, 1, 2, 3]
target = 0

输出:

-1

解释:

0不在数组中,返回-1。

挑战

O(logN) 时间限制

 

from typing import (
    List,
)

class Solution:
    """
    @param a: an integer rotated sorted array
    @param target: an integer to be searched
    @return: an integer
    """
    def search(self, a: List[int], target: int) -> int:
        # write your code here        
        def find_peak():
            l, r = 0, len(a) - 1
            while l < r - 1:
                mid = (l + r) >> 1
                if a[mid] > a[0]:
                    l = mid
                else:
                    r = mid
            
            if a[l] < a[r]:
                return r
            return  l

        def bin_search(l, r):            
            while l < r - 1:
                mid = (l + r) >> 1
                if a[mid] < target:
                    l = mid
                else:
                    r = mid
                        
            if a[l] == target:
                return l
            if a[r] == target:
                return r
            
            return -1

        if not a:
            return -1        

        if a[0] <= a[-1]:
            return bin_search(0, len(a)-1)

        peak = find_peak()    
        #在前半段搜索    
        if a[0] <= target <= a[peak]:
            return bin_search(0, peak)

        #在后半段搜索
        return bin_search(peak+1, len(a)-1)

逻辑非常简单清晰!!!不要再去用以前那种复杂的解法了。。。几个关系给你整蒙逼!!!

 

比如下面这种,就是用到夹逼的思想:

从两边不断靠近target的值。

class Solution:
    """
    @param A: an integer rotated sorted array
    @param target: an integer to be searched
    @return: an integer
    """
    def search(self, A, target):
        if not A:
            return -1
            
        start, end = 0, len(A) - 1
        while start + 1 < end:
            mid = (start + end) // 2
            if A[mid] >= A[start]:
                if A[start] <= target <= A[mid]:
                    end = mid
                else:
                    start = mid
            else:
                if A[mid] <= target <= A[end]:
                    start = mid
                else:
                    end = mid
                    
        if A[start] == target:
            return start
        if A[end] == target:
            return end
        return -1

 

if A[mid] >= A[start]:
                if A[start] <= target <= A[mid]: ==》表示在左半边升序部分

            else: if A[mid] <= target <= A[end]:==》表示在右半边升序部分

要求逻辑分析非常严谨。。。

 

 

标签:二分,return,target,mid,start,搜索,数组,integer
From: https://blog.51cto.com/u_11908275/6384678

相关文章

  • 多维数组遍历
    #include<stdio.h>intmain(){intarr[][3]={{1,2},{3,4,5}};inti=0;intj=0;intlen=0;for(i=0;i<2;i++){for(j=0;j<3;j++){printf("arr[%d][%d]:%d",i,j,arr[i][j]);}prin......
  • heapq 对有序的数组列表进行整体排序
     """功能:实现对有序的多个数组整体排序,获取topk个最小元素"""fromheapqimport*defheap_sort(arr,top_k):q=[]foriinrange(len(arr)):heappush(q,(arr[i][0],i,0))result=[]forkinrange(top_k):ifq:......
  • Gym - 101174F[(DSU)+树状数组]
    题目链接:https://vjudge.net/problem/Gym-101174F 解题思路:其实这题不同启发式合并也可以做,对rank排个序,然后在做个dfs序,把rank值小的先插入树状数组中更新,然后对每个节点查询它的dfs序的区间和就好了。对于DSU来说就更加无脑了,本来就是"暴力",所以我们直接DSU再加一个树状数组维......
  • Gym - 100851L [二分+线性推导]
    题目链接:https://vjudge.net/problem/Gym-100851L 解题思路:根据题目知道,墙的两边是不能放石头的,所以最终的结果肯定会收到两边墙的限制,从而使得答案不会超过1e9+1e5。此外我们再去二分最大高度,一个明显的结论就是以i为最高点建墙的话最少花费肯定是建一个金字塔形的墙面。但由于......
  • python二维数组切片
    随堂测试这道题错了,于是怒而发blog,是分割维度的标识符,如果对象是二维数组,则切片应当是x[,]的形式,逗号之前和之后分别表示对象的第0个维度和第1个维度;如果对象是三维数组,则切片应当是x[,,],里面有两个逗号,分割出三个间隔,三个间隔的前、中和后分别表示对象的第0、1、2个维度。每个......
  • wukong引擎源码分析之索引——part 1 倒排列表本质是有序数组存储
    searcher.IndexDocument(0,types.DocumentIndexData{Content:"此次百度收购将成中国互联网最大并购"})engine.go中的源码实现://将文档加入索引////输入参数://docId标识文档编号,必须唯一//data见DocumentIndexData注释////注意://1.这个函数是线程安全......
  • ES搜索排序,文档相关度评分介绍——Vector Space Model
    VectorSpaceModelThe vectorspacemodel providesawayof comparingamultitermqueryagainstadocument.Theoutputisasinglescorethatrepresentshowwellthedocumentmatchesthequery.Inordertodothis,themodelrepresentsboththedocumentan......
  • python二维数组初始化
    >>>a=[[0]*3foriinrange(3)]>>>a[[0,0,0],[0,0,0],[0,0,0]]>>>a[1][1]=121>>>a[[0,0,0],[0,121,0],[0,0,0]]>>>a[0][0]=11>>>a[[11,0,0],[0,121,0],[0,0,0]]>>>......
  • 数组中找最大值
    数组中找最大值#include<stdio.h>intmain(){ inta[]={3,2,5,8,4,7,6,9}; intlen=sizeof(a)/sizeof(a[0]); intmax=a[0]; for(inti=1;i<len;i++){ if(a[i]>max){ max=a[i]; } } printf("%d",max); retur......
  • 一维数组的动态和
    给你一个数组nums。数组「动态和」的计算公式为:runningSum[i]=sum(nums[0]…nums[i])。请返回nums的动态和。示例1:输入:nums=[1,2,3,4]输出:[1,3,6,10]解释:动态和计算过程为[1,1+2,1+2+3,1+2+3+4]。示例2:输入:nums=[1,1,1,1,1]输出:[1,2,3,4,5]解释:动态和......