每天一题LeetCode【第24天】

T33. Search in Rotated Sorted Array【Medium

题目

假设有一个升序的数组以某个未知的支点旋转。

(例如,0 1 2 3 4 5 6 7 可以变成 4 5 6 7 0 1 2

假设这个数组中没有重复的元素,给你一个 target(目标数),如果在这个数组中找到则返回它的 index,如果找不到就返回 -1

思路

首先,一般的有序的数组,查找一个数字一般都是用二分法,因为这样比较有效率。

按题中说法旋转数组后,分成的两半仍然是排好序的数组。

例如,4 5 6 7 0 1 2,左边的 4 5 6 7,以及右边的 0 1 2 都是排好序的,可以先确定 target 在哪边,然后继续二分查找。不过这个代码是从中间二分,分到的一半可能还是有两段排序的代码,需要继续分,就是很神奇的代码。

具体看代码以及注释~还是这句话,最好自己拿个例子试试,瞬间清晰!

信我 (ง •̀_•́)ง !

代码

代码取自 Top Solution,稍作注释

public int search(int[] nums, int target) {
        //定位数组头和尾
        int start = 0;
        int end = nums.length - 1;
        //start > end时表示里面不包含了,跳出循环
        while (start <= end){
            int mid = (start + end) / 2;
            //找到匹配值,返回index
            if (nums[mid] == target)
                return mid;
            //通过nums[start] <= nums[mid]表明start~mid这段是正确升序的
            if (nums[start] <= nums[mid]){
            //这就是二分法的做法,判断点在哪里,然后通过把start或者end赋予新的mid左右的值,表示选择前一段或者后一段
                 if (target < nums[mid] && target >= nums[start]) 
                    end = mid - 1;
                 else
                    start = mid + 1;
            } 
            //通过nums[mid] <= nums[end]表明mid ~ end这段是正确升序的
            if (nums[mid] <= nums[end]){
             //这就是二分法的做法,判断点在哪里,然后通过把start或者end赋予新的mid左右的值,表示选择前一段或者后一段
                if (target > nums[mid] && target <= nums[end])
                    start = mid + 1;
                 else
                    end = mid - 1;
            }
        }
        //不存在的,返回-1
        return -1;
    }

补充

注意啦~这里是代码里的东西要补充说一下!一开始不明白这代码为什么要这么多if。

这里是有对应关系的,先判断在 start~mid是升序的才能用 target < nums[mid] && target >= nums[start] ,来判断 target 在不在这一段,然后若不是才说是在 mid ~ end的。(希望只有我一个人最开始第一眼没有看出来 ╮(๑•́ ₃•̀๑)╭...)

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

你可能感兴趣的:(每天一题LeetCode【第24天】)