• [LeetCode] 81. Search in Rotated Sorted Array II


    There is an integer array nums sorted in non-decreasing order (not necessarily with distinct values).

    Before 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,4,4,5,6,6,7] might be rotated at pivot index 5 and become [4,5,6,6,7,0,1,2,4,4].

    Given the array nums after the rotation and an integer target, return true if target is in nums, or false if it is not in nums.

    Example 1:

    Input: nums = [2,5,6,0,0,1,2], target = 0
    Output: true
    

    Example 2:

    Input: nums = [2,5,6,0,0,1,2], target = 3
    Output: false

    Constraints:

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

    Follow up:

    • This is a follow up problem to Search in Rotated Sorted Array, where nums may contain duplicates.
    • Would this affect the run-time complexity? How and why?

    在旋转有序数组中搜索二。

    这题跟33题求的一样,多一个条件是input里面有重复数字。依然是用二分法做,但是worst case很可能会到O(n);而且其中一开始需要多一个case的判断,就是 nums[mid] 和 nums[start] ,nums[end] 的大小关系。因为在重复数字的数量超过数组一半的情况下,nums[mid] 和 nums[start] ,nums[end] 有可能都是相等的,此时需要将左右指针都分别往中间靠近,排除重复元素之后再判断。

    时间O(logn), worst case O(n)

    空间O(1)

    JavaScript实现

     1 /**
     2  * @param {number[]} nums
     3  * @param {number} target
     4  * @return {boolean}
     5  */
     6 var search = function(nums, target) {
     7     // corner case
     8     if (nums === null || nums.length === 0) {
     9         return false;
    10     }
    11 
    12     // normal case
    13     let start = 0;
    14     let end = nums.length - 1;
    15     while (start + 1 < end) {
    16         let mid = Math.floor(start + (end - start) / 2);
    17         if (nums[mid] === target) return true;
    18         if (nums[start] === nums[mid] && nums[mid] === nums[end]) {
    19             start++;
    20             end--;
    21         } else if (nums[start] <= nums[mid]) {
    22             if (nums[start] <= target && target <= nums[mid]) {
    23                 end = mid;
    24             } else {
    25                 start = mid;
    26             }
    27         } else if (nums[mid] <= nums[end]) {
    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 true;
    36     if (nums[end] === target) return true;
    37     return false;
    38 };

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

     1 class Solution {
     2     public boolean search(int[] nums, int target) {
     3         // corner case
     4         if (nums == null || nums.length == 0) {
     5             return false;
     6         }
     7 
     8         // normal case
     9         int start = 0;
    10         int end = nums.length - 1;
    11         while (start + 1 < end) {
    12             int mid = start + (end - start) / 2;
    13             if (nums[mid] == target) {
    14                 return true;
    15             }
    16             if (nums[start] == nums[mid] && nums[mid] == nums[end]) {
    17                 start++;
    18                 end--;
    19             } else if (nums[start] <= nums[mid]) {
    20                 if (nums[start] <= target && target <= nums[mid]) {
    21                     end = mid;
    22                 } else {
    23                     start = mid;
    24                 }
    25             } else if (nums[mid] <= nums[end]) {
    26                 if (nums[mid] <= target && target <= nums[end]) {
    27                     start = mid;
    28                 } else {
    29                     end = mid;
    30                 }
    31             }
    32         }
    33         if (nums[start] == target) {
    34             return true;
    35         }
    36         if (nums[end] == target) {
    37             return true;
    38         }
    39         return false;
    40     }
    41 }

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

     1 class Solution {
     2     public boolean 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 (nums[mid] == target) {
    10                 return true;
    11             }
    12             // 缩减重复元素的部分
    13             if (nums[start] == nums[mid] && nums[mid] == nums[end]) {
    14                 start++;
    15                 end--;
    16             }
    17             // target在左半段
    18             else if (nums[start] <= nums[mid]) {
    19                 if (nums[start] <= target && target <= nums[mid]) {
    20                     end = mid - 1;
    21                 } else {
    22                     start = mid + 1;
    23                 }
    24             }
    25             // target在右半段
    26             else if (nums[mid] <= nums[end]) {
    27                 if (nums[mid] <= target && target <= nums[end]) {
    28                     start = mid + 1;
    29                 } else {
    30                     end = mid - 1;
    31                 }
    32             }
    33         }
    34         return false;
    35     }
    36 }

    LeetCode 题目总结

  • 相关阅读:
    攻击
    url特殊字符转义及解决方法
    为解决Samba windows 无法访问 尝试过的方法
    两种JavaScript的AES加密方式(可与Java相互加解密)
    css 实现关闭按钮 X
    webpack 安装
    webpack 踩的坑
    npm start时报错 npm ERR!Windows_NT 6.1.7601
    点击文字,把input type="radio"也选中
    linux-正则表达式
  • 原文地址:https://www.cnblogs.com/cnoodle/p/11795870.html
Copyright © 2020-2023  润新知