leetcode算法整理33搜索旋转排序数组

LEETCODE算法注解33:
假设按照升序排序的数组在预先未知的某个点上进行了旋转。
( 例如,数组 [0,1,2,4,5,6,7] 可能变为 [4,5,6,7,0,1,2] )。
搜索一个给定的目标值,如果数组中存在这个目标值,则返回它的索引,否则返回 -1 。
你可以假设数组中不存在重复的元素。
你的算法时间复杂度必须是 O(log n) 级别。

示例 1:
输入: nums = [4,5,6,7,0,1,2], target = 0
输出: 4
示例 2:
输入: nums = [4,5,6,7,0,1,2], target = 3
输出: -1

解法:很明显,最初的思路时通过先找出旋转点,再做判断,去哪一部分中查找,还是直接顺序查找,两者的复杂度相同的都是O(n),不符合条件。题目要求
logn很明显是要求二分查找。此时已经与旋转点没有关系了,因为你查找旋转点的复杂度都为O(n)了。
我们要从旋转点发现新的规律:
旋转过后,将数组从中间分开,一半是必然有序的,另一半不确定。
如4 7 8 0 1 2 3已经旋转后得到,数组的下表[0~6], 4,7,8,0是无序的,1,2,3是有序的。target=7,我们发现7不属于有序的123,则target应该再4,7,8,0中寻找。查找过程与上面一样。这就是递归。

class Solution {
    public int search(int[] nums, int target) {
    //leetcode一般都须判断空
        if(nums.length==0) return -1;
        return ans(nums,target,0,nums.length-1);
    }
    public int ans(int[] nums, int target, int start, int end)
    {
        int mid = (start + end) / 2;
        if(nums[mid] == target) return mid;
        if(start <= end)
        {
         //考虑到start可能等于mid也算作有序因此<=
            if(nums[start]<=nums[mid])
            {
                if(target>=nums[start] && target<=nums[mid])
                {
                  return ans(nums,target,start,mid-1);
                }
                else
                {
                  return ans(nums,target,mid+1,end);
                }
            }
            else
            {
                if(target>=nums[mid] && target<=nums[end])
                {
                  return ans(nums,target,mid+1,end);
                }
                else
                {
                  return ans(nums,target,start,mid-1);
                }
            }
        }
        return -1;
    }
}
发布了5 篇原创文章 · 获赞 1 · 访问量 70

猜你喜欢

转载自blog.csdn.net/qq_39502383/article/details/104098787