leetcode 33. Search in Rotated Sorted Array
2017-10-27 23:31
387 查看
原题描述
Suppose an array sorted in ascending order 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.
翻译
假定一个数组在一个我们预先不知道的轴点旋转。 例如,0 1 2 4 5 6 7可能会变为4 5 6 7 0 1 2。 给你一个目标值去搜索,如果找到了则返回它的索引,否则返回-1。 你可以假定没有重复的元素存在于数组中。
分析思路
这个题看起来就是个二分查找的变形,所以思考下能否使用二分查找。首先可以确定这个旋转点pivot会有三种情况:
在mid处
在mid左侧
在mid右侧
[b]旋转点在mid左侧[/b]
情况1可以不考虑,因为target如果就是等于mid,二分查找肯定能找到了。情况2和3的分布和各部分对应大小关系可以见图1和图2。
先看看情况1,这是pivot位于mid左侧的情况,这时考虑target落在mid右边比较简单。而target要想落在mid右侧,则必须满足以下条件:
nums[mid]<target<=nums[rear]
再看看如果target不幸落入mid左边怎么办,落入左边,pivot其实仍然是三种情况:
在mid处
在mid左侧
在mid右侧
又重复了以上分析,所以没什么问题,再看看情况3.
[b]旋转点在mid右侧[/b]
很明显,如果pivot在mid右侧,那么pivot及其后面所有元素都要比nums[head]小,另外pivot及其后面所有元素也要比nums[mid]小。这个时候和旋转点在mid左侧一样,我们考虑target落在mid左侧更简单,需要满足的条件是:
nums[head]<=target<nums[mid]
所以,分析到这里使用二分查找完全可行,以下是代码。
代码
class Solution { public int search(int[] nums, int target) { int head = 0; int rear = nums.length - 1; while(head <= rear){ int mid = (head+rear)/2; if(target == nums[mid]){ return mid; } else if(nums[mid] < nums[rear]){ //根据以上分析,满足该条件则说明pivot在mid左侧 //target在右侧 if(nums[mid]<target && target<=nums[rear]) head = mid + 1; else rear = mid - 1; } else { //pivot在mid右侧 //target在左侧 if(nums[head]<=target && target<nums[mid]) rear = mid - 1; else head = mid + 1; } } return -1; } }
扩展
该题我们一直在避开pivot,但还可以扩展一下:如何找到该旋转点的位置pivot?这个题也是类似上面的分析,稍微有点区别的地方在于,通过什么样的标准来判断这个pivot。其实我们可以从图1图2看出,pivot需要满足的条件:
{nums[pivot−1]<nums[pivot]} && {nums[pivot]<nums[pivot+1]}
也就是说pivot的左右都比它大。
[b]代码[/b]
public static int search(int[] arr) { int head = 0; int rear = arr.length - 1; while (head <= rear) { int mid = (head + rear) / 2; boolean isPivot = false; //考虑两个边界条件 if (mid == 0) isPivot = arr[mid] > arr[mid + 1]; else if (mid == arr.length - 1) isPivot = arr[mid - 1] > arr[mid]; else isPivot = arr[mid - 1] > arr[mid] && arr[mid] < arr[mid + 1]; if (isPivot) { return mid; } else if (arr[mid] < arr[rear]) {//pivot在mid左侧 rear = mid - 1; } else {//pivot在mid右侧 head = mid + 1; } } return 0; }
这个扩展题当然直接通过遍历是最简单的,但是事件复杂度是O(n),而使用二分查找的思想,则时间复杂度是O(lgn)。
相关文章推荐
- leetcode-33 Search in Rotated Sorted Array
- [LeetCode]33. Search in Rotated Sorted Array
- [leetcode 33] Search in Rotated Sorted Array
- leetcode 33 : Search in Rotated Sorted Array
- 算法分析与设计——LeetCode:33. Search in Rotated Sorted Array
- Leetcode 33 Search in Rotated Sorted Array
- LeetCode 33.Search in Rotated Sorted Array
- LeetCode 33. Search in Rotated Sorted Array && 81. Search in Rotated Sorted Array II
- LeetCode - 33. Search in Rotated Sorted Array
- [leetcode] 33. Search in Rotated Sorted Array
- [leetcode]33. Search in Rotated Sorted Array(Java实现)
- Leetcode 33. Search in Rotated Sorted Array
- leetcode(33). Search in Rotated Sorted Array
- leetcode 33: Search in Rotated Sorted Array
- Leetcode题解-33. Search in Rotated Sorted Array
- LeetCode 33: Search in Rotated Sorted Array
- LeetCode --- 33. Search in Rotated Sorted Array
- 【Leetcode】33. Search in Rotated Sorted Array
- Leetcode[33]-Search in Rotated Sorted Array
- leetcode 33. Search in Rotated Sorted Array