• [LeetCode] 33. Search in Rotated Sorted Array


    There is an integer array nums sorted in ascending order (with distinct values).

    Prior to being passed to your function, nums is rotated at an unknown pivot index k (0 <= k < nums.length) such that the resulting array is [nums[k], nums[k+1], ..., nums[n-1], nums[0], nums[1], ..., nums[k-1]] (0-indexed). For example, [0,1,2,4,5,6,7] might be rotated at pivot index 3 and become [4,5,6,7,0,1,2].

    Given the array nums after the rotation and an integer target, return the index of target if it is in nums, or -1 if it is not in nums.

    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
    

    Example 3:

    Input: nums = [1], target = 0
    Output: -1

    Constraints:

    • 1 <= nums.length <= 5000
    • -104 <= nums[i] <= 104
    • All values of nums are unique.
    • nums is guaranteed to be rotated at some pivot.
    • -104 <= target <= 104

    Follow up: Can you achieve this in O(log n) time complexity?

    在旋转有序数组中搜索。

    整数数组 nums 按升序排列,数组中的值 互不相同 。

    在传递给函数之前,nums 在预先未知的某个下标 k(0 <= k < nums.length)上进行了 旋转,使数组变为 [nums[k], nums[k+1], ..., nums[n-1], nums[0], nums[1], ..., nums[k-1]](下标 从 0 开始 计数)。例如, [0,1,2,4,5,6,7] 在下标 3 处经旋转后可能变为 [4,5,6,7,0,1,2] 。

    给你 旋转后 的数组 nums 和一个整数 target ,如果 nums 中存在这个目标值 target ,则返回它的下标,否则返回 -1 。

    来源:力扣(LeetCode)
    链接:https://leetcode-cn.com/problems/search-in-rotated-sorted-array
    著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

    这题grandyang大神的解释我直接搬过来了,非常详细。注意二分找到mid的位置之后,其实左半边和右半边是有可能都是有序的,所以需要额外判断到底是动 start 还是动 end。跳出 while 循环之后,因为 while的条件是 start + 1 < end 所以跟 153,154 题类似,跳出 while 的时候满足 start < end。所以需要再判断 target 是否在 start 或者在 end。

    时间O(logn)

    空间O(1)

    JavaScript实现

     1 /**
     2  * @param {number[]} nums
     3  * @param {number} target
     4  * @return {number}
     5  */
     6 var search = function(nums, target) {
     7     // corner case
     8     if (nums === null || nums.length === 0) return -1;
     9 
    10     // normal case
    11     let start = 0;
    12     let end = nums.length - 1;
    13     while (start + 1 < end) {
    14         let mid = Math.floor(start + (end - start) / 2);
    15         if (nums[mid] === target) {
    16             return mid;
    17         }
    18         // if target is on the left side
    19         if (nums[start] < nums[mid]) {
    20             if (nums[start] <= target && target <= nums[mid]) {
    21                 end = mid;
    22             } else {
    23                 start = mid;
    24             }
    25         }
    26         // if target is on the right side
    27         else {
    28             if (nums[mid] <= target && target <= nums[end]) {
    29                 start = mid;
    30             } else {
    31                 end = mid;
    32             }
    33         }
    34     }
    35     if (nums[start] === target) return start;
    36     if (nums[end] === target) return end;
    37     return -1;
    38 };

    Java实现一,while (start + 1 < end)

     1 class Solution {
     2     public int search(int[] nums, int target) {
     3         int start = 0;
     4         int end = nums.length - 1;
     5         // start + 1 < end
     6         // 举例,start - 0, end = 3
     7         // 中间隔了起码有start + 1和start + 2两个下标
     8         // 这样跳出while循环的时候,end < start
     9         // 才有了最后的两个特判
    10         while (start + 1 < end) {
    11             int mid = start + (end - start) / 2;
    12             if (nums[mid] == target) {
    13                 return mid;
    14             }
    15             // left half is increasing
    16             if (nums[start] < nums[mid]) {
    17                 if (nums[start] <= target && target <= nums[mid]) {
    18                     end = mid;
    19                 } else {
    20                     start = mid;
    21                 }
    22             }
    23             // right half is increasing
    24             else {
    25                 if (nums[mid] <= target && target <= nums[end]) {
    26                     start = mid;
    27                 } else {
    28                     end = mid;
    29                 }
    30             }
    31         }
    32         if (nums[start] == target) {
    33             return start;
    34         }
    35         if (nums[end] == target) {
    36             return end;
    37         }
    38         return -1;
    39     }
    40 }

    Java实现二,while (start <= end)

    如果是 <= 则说明二分法的两端是闭区间 [start, end] ;如果写成start + 1 < end,其实是在start和end之间预留了两个空格,在跳出while循环后要额外判断。

     1 class Solution {
     2     public int search(int[] nums, int target) {
     3         int start = 0;
     4         int end = nums.length - 1;
     5         // start <= end最后跳出while循环的时候end < start
     6         // end和start是邻近的两个index,所以无需特判
     7         while (start <= end) {
     8             int mid = start + (end - start) / 2;
     9             if (target == nums[mid]) {
    10                 return mid;
    11             }
    12             // 左半段是有序的
    13             if (nums[start] <= nums[mid]) {
    14                 // target 在这段里
    15                 if (target >= nums[start] && target < nums[mid]) {
    16                     end = mid - 1;
    17                 } else {
    18                     start = mid + 1;
    19                 }
    20                 // 右半段是有序的
    21             } else {
    22                 if (target > nums[mid] && target <= nums[end]) {
    23                     start = mid + 1;
    24                 } else {
    25                     end = mid - 1;
    26                 }
    27             }
    28         }
    29         return -1;
    30     }
    31 }

    LeetCode 题目总结

  • 相关阅读:
    PCB Genesis加邮票孔(邮票孔增加方向判断--左右上下)实现算法
    PCB SLOT槽孔数量计算方法,同CAM350孔数一致 实现方法
    从上到下打印二叉树II
    数据结构与算法(2)---顺序表
    栈的压入弹出序列
    包含min函数的栈
    顺时针打印矩阵
    数据结构与算法(1)--绪论
    反转链表
    数值的整数次方(快速幂)
  • 原文地址:https://www.cnblogs.com/cnoodle/p/11791870.html
Copyright © 2020-2023  润新知