• 【数据结构】算法 搜索旋转排序数组 Search in Rotated Sorted Array II


    搜索旋转排序数组 Search in Rotated Sorted Array II

    There is an integer array nums sorted in non-decreasing order (not necessarily with distinct values).

    Before being passed to your function, nums is rotated at an unknown pivot index k (0 <= k < nums.length) such that the resulting array is [nums[k], nums[k+1], ..., nums[n-1], nums[0], nums[1], ..., nums[k-1]] (0-indexed). For example, [0,1,2,4,4,4,5,6,6,7] might be rotated at pivot index 5 and become [4,5,6,6,7,0,1,2,4,4].

    Given the array nums after the rotation and an integer target, return true if target is in nums, or false if it is not in nums.

    就是有一个按非降序排列的整数数组nums,在传给函数之前,nums在下标k上做了旋转,上面有个例子,然后判断一个整数target是否存在于数组中,如果存在target返回true

    nums = [2,5,6,0,0,1,2], target = 0
    true
    
    nums = [2,5,6,0,0,1,2], target = 3
    false
    

    思路

    首先查找元素这个事,暴力点就是从头找,这个肯定不考虑了,会for的都会写。

    其实nums 没有旋转之前,它是一个非降序排列的,我们可以使用二分来查找。但是旋转后,nums就不再严格是一个非降序排列的数组。它会变成一个类似锯齿形的排列,也就是说它的单调性会变成2段。

    假设nums1,nums2是旋转后的2段。

    可能出现的情况:

    1 nums1的前一部分,nums2的后一部分和target相等,这个情况下直接返回true

    2如果不相等,那就先将两端相同的元素剔除,剩下的nums1的首元素一定比nums2的尾元素要大。

    假设nums1的首元素为head,nums2的尾元素为tail

    在这个情况下,

    情况a: 当nums[mid]<=tail,那么说明此时mid一定落在nums2的区间内;

    情况b: 当nums[mid]>tail,那么说明此时mid一定落在nums1的区间内;

    当情况a下,nums[mid]<target<=nums[tail],说明如果存在target,那么一定在nums2区间的后半段内并且满足target下标属于(mid,tail]此时的head要调整到mid+1,此时可以使用二分;但是如果target不属于

    (mid,tail],此时就要调整tail到mid-1;

    当情况b下,nums[head]<=target<nums[mid],说明如果存在target,那么一定在nums1区间的前半段并且满足target下标属于(head,mid),此时调整tail到mid,此时可以使用二分;否则target可能存在于nums1后面直到tail,调整head到mid+1;

    不管二分如何调整head tail,都是为了将target包含在[head,tail]内。

    public boolean search(int[] nums, int target) {
            if(nums[0]==target||nums[nums.length-1]==target){
                return true;
            }
            int l = 0;
            int r = nums.length -1;
            int mid,head,tail;
            while(l<nums.length&&nums[l]==nums[0]){
                ++l;
            }
            while(r>=0&&nums[r]==nums[0]){
                --r;
            }
            head = l;
            tail = r;
            while(l<=r){
                mid= (l+r)>>1;
                if(nums[mid]==target){
                    return true;
                }
                if (nums[mid]<=nums[tail]){
                    if (nums[mid]<target&&target<=nums[tail]){
                        l = mid+1;
                    }
                    else{
                        r = mid -1;
                    }
                }
                else{
                    if (nums[mid]>target&&nums[head]<=target){
                        r = mid-1;
                    }
                    else{
                        l = mid +1;
                    }
                }
            }
            return false;
        }
    
    

    Tag

    binary search

  • 相关阅读:
    关于动态规划的问题494_LEETCODE_TARGET_SUM
    Python 关于二叉树生成、先序遍历、中序遍历、后序遍历、反转
    关于python引入文件路径的解决办法
    git一些笔记
    迪克斯特拉 算法(算最短距离)
    Python多线程编程中daemon属性的作用
    types.MethodType实例绑定方法
    Python之__getitem__、__getattr__、__setitem__ 、__setitem__ 的区别
    jenkins自动打包ios、安卓
    python socket编程tcp/udp俩连接
  • 原文地址:https://www.cnblogs.com/dreamtaker/p/15153218.html
Copyright © 2020-2023  润新知