Search in Rotated Sorted Array I
Search in Rotated Sorted Array I
Suppose a sorted array is rotated at some pivot unknown to you beforehand.
(i.e., 0 1 2 4 5 6 7 might become 4 5 6 7 0 1 2).
You are given a target value to search. If found in the array return its index, otherwise return -1.
You may assume no duplicate exists in the array.
二分法
复杂度
时间 O(logN) 空间 O(1)
思路
平时我们二分法的时候,直接判断下中点和目标的关系,就可以知道目标在左半部分还是右半部份了,这背后其实隐含一个假设,那就是从起点到终点是一段有序的序列。而本题中,如果我们还想继续做二分法,这个假设就不存在了,因为从起点到终点有可能有个断片!不过,旋转有序数组有一个特点,假设本身是个升序序列,从左向右。如果左边的点比右边的点小,说明这两个点之间是有序的,不存在旋转点。如果左边的点比右边的大,说明这两个点之间有一个旋转点,导致了不再有序。因为只有一个旋转点,所以一分为二后,肯定有一半是有序的。所以,我们还是可以用二分法,不过要先判断左半边有序还是右半边有序。如果左半边有序,则直接将目标和左半边的边界比较,就知道目标在不在左半边了,如果不在左半边肯定在右半边。同理,如果右半边有序,则直接将目标和右半边的边界比较,就知道目标在不在右半边了,如果不在右半边肯定在左半边。这样就完成了二分。
注意
这里要注意二分时候的边界条件,一般来说我们要找某个确定的目标时,边界条件为:
min = 0, max = length - 1;
if(min <= max){
    min = mid + 1
    max = mid - 1
}
另外,判断左半边是否有序的条件是:nums[min] <= nums[mid],而判断是否在某一个有序区间,则要包含那个区间较远的那一头
代码
迭代写法
public class Solution {
    public int search(int[] nums, int target) {
        int min = 0, max = nums.length - 1, mid = 0;
        while(min <= max){
            mid = (min + max) / 2;
            if(nums[mid] == target){
                return mid;
            }
            // 如果左半部分是有序的
            if(nums[min] <= nums[mid]){
                if(nums[min] <= target && target < nums[mid]){
                    max = mid - 1;
                } else {
                    min = mid + 1;
                }
            // 如果右半部份是有序的
            } else {
                if(nums[mid] < target && target <= nums[max]){
                    min = mid + 1;
                } else {
                    max = mid - 1;
                }
            }
        }
        // 不满足min <= max条件时,返回-1
        return -1;
    }
}递归写法
public class Solution {
    public int search(int[] nums, int target) {
        return helper(nums, 0, nums.length - 1, target);
    }
    public int helper(int[] nums, int min, int max, int target){
        int mid = min + (max - min) / 2;
        // 不满足min <= max条件时,返回-1
        if(min > max){
            return -1;
        }
        if(nums[mid] == target){
            return mid;
        }
        // 如果左半部分是有序的
        if(nums[min] <= nums[mid]){
            // 如果在左半部分的边界内
            if(nums[min] <= target && target < nums[mid]){
                return helper(nums, min, mid - 1, target);
            // 如果不在左半部分的边界内
            } else {
                return helper(nums, mid + 1, max, target);
            }
        // 如果右半部份是有序的
        } else {
            // 如果在右半部分的边界内
            if(nums[mid] < target && target <= nums[max]){
                return helper(nums, mid + 1, max, target);
            // 如果不在右半部分的边界内
            } else {
                return helper(nums, min, mid - 1, target);
            }
        }
    }
}
Search in Rotated Sorted Array II
Follow up for "Search in Rotated Sorted Array": What if duplicates are allowed?
Would this affect the run-time complexity? How and why?
Write a function to determine if a given target is in the array.
二分法
复杂度
时间 O(N) 空间 O(1)
思路
如果可能有重复,那我们之前判断左右部分是否有序的方法就失效了,因为可能有这种13111情况,虽然起点小于等于中间,但不代表右边就不是有序的,因为中点也小于等于终点,所有右边也是有序的。所以,如果遇到这种中点和两边相同的情况,我们两边都要搜索。
代码
public class Solution {
    public boolean search(int[] nums, int target) {
        return helper(nums, 0, nums.length - 1, target);
    }
    public boolean helper(int[] nums, int min, int max, int target){
        int mid = min + (max - min) / 2;
        // 不符合min <= max则返回假
        if(min > max){
            return false;
        }
        if(nums[mid] == target){
            return true;
        }
        boolean left = false, right = false;
        // 如果左边是有序的
        if(nums[min] <= nums[mid]){
            // 看目标是否在左边有序数列中
            if(nums[min] <= target && target < nums[mid]){
                left = helper(nums, min, mid - 1, target);
            } else {
                left = helper(nums, mid + 1, max, target);
            }
        }
        // 如果右边也是有序的
        if(nums[mid] <= nums[max]){
            // 看目标是否在右边有序数列中
            if(nums[mid] < target && target <= nums[max]){
                right = helper(nums, mid + 1, max, target);
            } else {
                right = helper(nums, min, mid - 1, target);
            }
        }
        // 左右两边有一个包含目标就返回真
        return left || right;
    }
}Search in Rotated Sorted Array I的更多相关文章
- [LeetCode] Search in Rotated Sorted Array II 在旋转有序数组中搜索之二
		Follow up for "Search in Rotated Sorted Array":What if duplicates are allowed? Would this ... 
- [LeetCode] Search in Rotated Sorted Array 在旋转有序数组中搜索
		Suppose a sorted array is rotated at some pivot unknown to you beforehand. (i.e., 0 1 2 4 5 6 7 migh ... 
- 【leetcode】Search in Rotated Sorted Array II
		Search in Rotated Sorted Array II Follow up for "Search in Rotated Sorted Array":What if d ... 
- 【leetcode】Search in Rotated Sorted Array
		Search in Rotated Sorted Array Suppose a sorted array is rotated at some pivot unknown to you before ... 
- 【leetcode】Search in Rotated Sorted Array II(middle)☆
		Follow up for "Search in Rotated Sorted Array":What if duplicates are allowed? Would this ... 
- 49. Search in Rotated Sorted Array   &&  Search in Rotated Sorted Array II
		Search in Rotated Sorted Array Suppose a sorted array is rotated at some pivot unknown to you before ... 
- Search in Rotated Sorted Array II leetcode
		原题链接,点我 该题解题参考博客 和Search in Rotated Sorted Array唯一的区别是这道题目中元素会有重复的情况出现.不过正是因为这个条件的出现,出现了比较复杂的case,甚至 ... 
- [CareerCup] 11.3 Search in Rotated Sorted Array 在旋转有序矩阵中搜索
		11.3 Given a sorted array of n integers that has been rotated an unknown number of times, write code ... 
- LeetCode:Search in Rotated Sorted Array I II
		LeetCode:Search in Rotated Sorted Array Suppose a sorted array is rotated at some pivot unknown to y ... 
随机推荐
- [Cocos2d-x For WP8]EaseActions缓动动作
			我们用Silverlight框架开发WP8的应用程序的时,编写动画可以使用缓动效果来实现缓动动画对吧,那么在Cocos2d-x框架里面我们一样是可以缓动动作(缓动动画),其实技术的东西都是想通的,如果 ... 
- 【BZOJ】1503: [NOI2004]郁闷的出纳员(Splay)
			http://www.lydsy.com/JudgeOnline/problem.php?id=1503 这题没有看题解就1a了-好开心,, 其实后面去看题解发现他们的都很麻烦,其实有种很简单的做法: ... 
- COJ883 工艺品
			试题描述 LZJ和XJR是一对好朋友. 他们现在要做一个由方块构成的长条工艺品.但是方块现在是乱的,而且由于机器的要求,他们只能做到把这个工艺品最左边的方块放到最右边. 他们想,在仅这一个操作下,最漂 ... 
- HttpClient工具类v1.7
			package com.cucpay.fundswap.util; import java.io.IOException; import java.net.SocketTimeoutException ... 
- OpenCV Show Image cvShowImage() 使用方法
			新版的OpenCV在所有的函数和类前都加上了cv或Cv,这样很好的避免了区域污染(namespace pollution),而且不用在前面加‘cv::’,非常的使用.像之前的imshow()函数被现在 ... 
- 【iCore2双核心板】SRAM 读写实验(基于Verilog语言)
			_____________________________________ 深入交流QQ群: A: 204255896(1000人超级群,可加入) B: 165201798(500人超级群,满员) C ... 
- activeform 配置
			<?php $form = ActiveForm::begin([ 'action' => ['/admin/admin/adminadd'], 'id' => 'login-for ... 
- ScrollFix.js:一个 iOS5 溢出滚动的(有限)修复方案
			Update: Unfortunately this does not 100% solve the problem, the script falls down when handling touc ... 
- CSS3系列:魔法系列
			一.三角形 #wrap div{ margin: 0 auto; } .triangle_three { height:0px; width:0px; border-bottom:50px solid ... 
- ExpandableListView实现子Item的点击事件
			在继承的BaseExpandableListAdapter的ExpandableListView的Adapter中,重写以下方法 @Override public boolean isChildSel ... 
