简体   繁体   中英

Search in Rotated Sorted Array( with algorithm )

I am trying to search for a target in rotated sorted ascending array in O(logn) time

For example:

Example 1:

Input: nums = [4,5,6,7,0,1,2], target = 0
Output: 4
Example 2:

Input: nums = [4,5,6,7,0,1,2], target = 3
Output: -1

My idea is that, in the rotated array, the whole sequence is not said to be sorted anymore.

But I found that if I give a cut in the middle, either the first half or second half is still sorted.

So, I pick the middle one and compare the values on both ends to check which part is still sorted. Then I check if the target is within the sorted range. And I am doing it recursively

Here is my code:

var search = function(nums, target) {
    let start = 0 
    let end = nums.lenght -1; 
    let mid = 0; 

    while (start<=end){
        mid = (start + end) / 2
        if (target == nums[mid]){
            return mid
        }
        else{
            if (nums[mid]>nums[start] && nums[start]<taget<nums[mid]){
                end = mid; 
            }else {
                start = mid
            }
        }
        
    }
    return -1; 
};

But I still got an error for such input [4,5,6,7,0,1,2], 0; but output -1; I dont get why algorithm doesnt work and see the lacking. Can anyone see my faults?

----- second update --- corrected misspelled and condition sytax error

var search = function(nums, target) {
    let start = 0 
    let end = nums.length -1; 
    let mid = 0; 

    while (start<=end){
        mid = (start + end) / 2
        if (target == nums[mid]){
            return mid
        }
        else{
            if (nums[mid]>nums[start]){ //it means it is ascending and sorted...
                
                if(nums[start]<target && target<nums[mid]){                         // if target is within the range, then it could only be possible to go first half
                   end = mid;  
                }
           // it means the second half is sorted one otherwise     
            }else {
                start = mid
            }
        }
        
    }
    return -1; 
};

This passed the first case;

[2,5,6,0,0,1,2]
0

but got time exceeded on this

[2,5,6,0,0,1,2], target = -1

------ third edit, never expected it is so hard; I come up with 3 case to check... but not finished yet. I dont know which part went. wrong

var search = function(nums, target) {
    let start = 0 
    let end = nums.length -1; 
    let mid = 0; 

    while (start<=end){
        mid = (start + end) / 2
        if (target == nums[mid]){
            return mid
        }
        else{
            
            //case1 + (sorted first half) +(sorted second half)
             if (nums[mid]>nums[start] && num[mid]<nums[end]){
                 if(nums[start]<target && target<nums[mid]){
                     end = mid;  
                 }else{
                     start=mid;
                 }
             }
            
            
            //case2  + -  (sorted first half) +(unsorted second half)
            else if (nums[mid]>nums[start] && num[mid]>nums[end]){
                if(nums[start]<target && target<nums[mid]){
                    end = mid;  
                }else{
                    start = mid
                }
            }
            
            //case3 - +  (unsorted first half) +(sorted second half)
             else {
                if(nums[end]<target && target>nums[mid]){
                    start = mid;  
                }else{
                    end = mid
                }
            }
    }
    return -1; 
};

but I dont have any line 75; my line goes to til line 47 only在此处输入图像描述

-------------forth edit I looked again the pattern and come up with a clearer observation. This passed one of the case. but got Time Limit Exceeded in this case:

[2,5,6,0,0,1,2]
3 

var search = function(nums, target) {
    let left = 0 
    let right = nums.length -1; 
    let mid = 0; 

    while (left<=right){
        mid = (left + right) / 2
        if (target == nums[mid]){
            return mid
        }
        else{
            
     
             if (nums[mid] < nums[right]){
                 if(nums[mid]<target && target<nums[right]){
                      left = mid;  
                 }else{
                     right=mid;
                 }
             }else{
                 if(nums[mid]>target && target<nums[right]){
                     left = mid;  
                 }else{
                     right=mid;
                 }
                 
             }
        }
                    
    }
    return -1; 
};

Ok, you have corrected the misspelled and syntax errors, let's think about the cases you could encounter:

  1. The list is in order.
  2. The list is rotated.

If the list is in order, you can apply the classic algorithm. If the list is rotated, there is one point at which the number goes from highest to lowest. As this point is unique (think about why this is always true) it can be only in one half of the list, meaning one is in order, the other is a rotated list. (It could also be in between the 2 halves, meaning both of them are in order, but this is an easy case).

Thus you need to split the list in half, and determine in which half the target could be (could the target be in both halves?): to do that, first check which half is sorted, then check if the targer could be in that half (by using the first and last value). If it can't, it's in the rotated half.

Then, if the target is in the sorted half, you continue with the classic algorithm, else you search the target in the rotated half, which is like searching the target in a rotated list.

--Old answer for history--

Not sure if it's that, but you misspelled nums.length in the setup, which then set end to NaN (not a number), and thus the while loop is never entered(NaN comparaisons never hold true), and you return -1.

Also, there are multiples errors on line if (nums[mid]>nums[start] && nums[start]<taget<nums[mid]){ :

  1. target is misspelled
  2. You can't compare A < x < B in one go, you need to do A < x && x < B
  3. If the target is in the first half but it's not sorted (mid < x < start), you will search in the second half. You probably need 4 different cases there.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM