33. Search in Rotated Sorted Array

题目:

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.

链接:https://leetcode.com/problems/search-in-rotated-sorted-array/#/description

4/14/2017

23ms,4%

注意:

第13行开始的情况不能简单的判断,整体被划分了3个区间。如果没有第9,10行的判断,就需要在第14,15行跟首尾比较时加上相等的情况。(!不是那么简单的,=要在连续区间里,比如说按照下面的写法第14行不应该=,第17行应该=,原因是14行是2段区间,17行是连续的)

 1 public class Solution {
 2     public int search(int[] nums, int target) {
 3         if (nums.length == 0) return -1;
 4         int lo = 0, hi = nums.length - 1;
 5         int mid;
 6         
 7         while (lo <= hi) {
 8             mid = lo + (hi - lo) / 2;
 9             if (target == nums[lo]) return lo;
10             else if (target == nums[hi]) return hi;
11             else if (target == nums[mid]) return mid;
12             else {
13                 if (nums[lo] < nums[mid]) {
14                     if (target < nums[lo] || target > nums[mid]) lo = mid + 1;
15                     else hi = mid - 1;
16                 } else {
17                     if (nums[mid] < target && target < nums[hi]) lo = mid + 1;
18                     else hi = mid - 1;
19                 }
20             }
21         }
22         return -1;
23     }
24 }

按照直观的写法:15ms, 58%。排除网络因素,为什么performance变化这么大?我做的改变:

1. 去掉了和lo,hi相等的判断,并且更改了第12行,15行的判断(没有大变化)

2. 将第12行,13行调整顺序(大变化,也许就是or --> and少判断一步的区别?)

 1 public class Solution {
 2     public int search(int[] nums, int target) {
 3         if (nums.length == 0) return -1;
 4         int lo = 0, hi = nums.length - 1;
 5         int mid;
 6         
 7         while (lo <= hi) {
 8             mid = lo + (hi - lo) / 2;
 9             if (target == nums[mid]) return mid;
10             else {
11                 if (nums[lo] <= nums[mid]) {
12                     if (target >= nums[lo] && target < nums[mid]) hi = mid - 1;
13                     else lo = mid + 1;
14                 } else {
15                     if (nums[mid] < target && target <= nums[hi]) lo = mid + 1;
16                     else hi = mid - 1;
17                 }
18             }
19         }
20         return -1;
21     }
22 }

别人相同思路,但是performance好很多,15ms,主要是最后第23行的判断

 1 public int search(int[] A, int target) {
 2     if (A.length == 0) return -1;
 3     int lo = 0;
 4     int hi = A.length - 1;
 5     while (lo < hi) {
 6         int mid = (lo + hi) / 2;
 7         if (A[mid] == target) return mid;
 8         
 9         if (A[lo] <= A[mid]) {
10             if (target >= A[lo] && target < A[mid]) {
11                 hi = mid - 1;
12             } else {
13                 lo = mid + 1;
14             }
15         } else {
16             if (target > A[mid] && target <= A[hi]) {
17                 lo = mid + 1;
18             } else {
19                 hi = mid - 1;
20             }
21         }
22     }
23     return A[lo] == target ? lo : -1;
24 }

其他人的解法:

非常好的思路,将不合格的区间视为-inf, inf,不需要改值,但是可以以=作为nums[mid]来判断。

https://discuss.leetcode.com/topic/34491/clever-idea-making-it-simple

https://discuss.leetcode.com/topic/34467/pretty-short-c-java-ruby-python

 1 int search(vector<int>& nums, int target) {
 2     int lo = 0, hi = nums.size();
 3     while (lo < hi) {
 4         int mid = (lo + hi) / 2;
 5         
 6         double num = (nums[mid] < nums[0]) == (target < nums[0])
 7                    ? nums[mid]
 8                    : target < nums[0] ? -INFINITY : INFINITY;
 9                    
10         if (num < target)
11             lo = mid + 1;
12         else if (num > target)
13             hi = mid;
14         else
15             return mid;
16     }
17     return -1;
18 }

更多讨论:

https://discuss.leetcode.com/category/41/search-in-rotated-sorted-array

4/25/2017

算法班

思路
用二分法,判断target的区间。

用这个方法来做这道题!
如果A[mid] > A[start]并且target在它们之间,往前找。否则往后找。注意后面还是一个Sorted Array!
如果A[mid] < A[end]并且target在它们之间,往后找。否则往前找。注意前面还是一个Sorted Array!

 1 public class Solution {
 2     /** 
 3      *@param A : an integer rotated sorted array
 4      *@param target :  an integer to be searched
 5      *return : an integer
 6      */
 7     public int search(int[] A, int target) {
 8         // write your code here
 9         if (A == null || A.length == 0) return -1;
10         
11         int start = 0, end = A.length - 1;
12         
13         while (start + 1 < end) {
14             int mid = start + (end - start) / 2;
15             if (A[mid] == target) return mid;
16             else if (A[start] < A[mid]) {
17                 if (A[start] <= target && target < A[mid]) {
18                     end = mid;
19                 } else {
20                     start = mid;
21                 }
22             } else {
23                 if (A[mid] < target && target <= A[end]) {
24                     start = mid;
25                 } else {
26                     end = mid;
27                 }
28             }
29         }
30         if (A[start] == target) return start;
31         if (A[end] == target) return end;
32         return -1;
33     }
34 }
原文地址:https://www.cnblogs.com/panini/p/6712460.html