zoukankan      html  css  js  c++  java
  • LeetCode 新题: Find Minimum in Rotated Sorted Array II 解题报告-二分法模板解法

    扭转数组

    Find Minimum in Rotated Sorted Array II
    Follow up for "Find Minimum in Rotated Sorted Array":
    What if duplicates are allowed?

    Would this affect the run-time complexity? How and why?
    Suppose a sorted array 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).

    Find the minimum element.

    The array may contain duplicates.

    SOLUTION 1:

    请参考前一个题目Find Minimum in Rotated Sorted Array

    1. 如何找中间断开的区间(也就是说旋转过)
    我们的目的是要找出存在断口的地方。所以我们可以每次求一下mid的值,把mid 跟左边比一下,如果是正常序,就丢掉左边,反之丢掉右边,不断反复直到找到断口。
    分析一下:
    比如4 5 6 7 0 1 2  从中间断开后,它是由一个有序跟一个无序的序列组成的。
    如果left = 0, right = 6,mid = 3, 那么4, 5, 6, 7 是正序, 7, 0, 1, 2是逆序,所以我们要丢掉左边。这样反复操作,直到数列中只有2个数字,就是断开处,这题我们会得到7,0,返回后一个就可以了。

    以下图示简单描述了通过三步操作逐步逼近断口处。每一次我们可以扔掉一半,速度是LogN.

    【Leetcode】Find <wbr>Minimum <wbr>in <wbr>Rotated <wbr>Sorted <wbr>Array <wbr>解题报告

    2. 特别的情况:

    如果发现 A.mid > A.left,表示左边是有序,丢掉左边。

    如果发现 A.mid < A.left, 表示无序的状态在左边,丢掉右边

    如果A.mid = A.left,说明无法判断。这时我们可以把left++,丢弃一个即可。不必担心丢掉我们的目标值。因为A.left == A.mid,即使丢掉了left,还有mid在嘛!

    每次进入循环,我们都要判断A.left < A.right,原因是,前面我们丢弃一些数字时,有可能造成余下的数组是有序的,这时应直接返回A.left! 否则的话 我们可能会丢掉解。

    就像以下的例子,在1 10 10中继续判断会丢弃1 10.

    举例: 10 1 10 10 如果我们丢弃了最左边的10,则1 10 10 是有序的

    3.对复杂度的影响:

    题目中问到了,对复杂度有何影响:实际上是有的,如果全部的数字相等,我们就退化为O(N),但是平均的复杂度仍然是O(LogN),最后复杂度的大小取决于重复的数字的多少。如果重复字数少,与logN相差不大。

     1 public class Solution {
     2     public int findMin(int[] num) {
     3         if (num == null || num.length == 0) {
     4             return 0;
     5         }
     6         
     7         int len = num.length;
     8         if (len == 1) {
     9             return num[0];
    10         } else if (len == 2) {
    11             return Math.min(num[0], num[1]);
    12         }
    13         
    14         int left = 0;
    15         int right = len - 1;
    16         
    17         while (left < right - 1) {
    18             int mid = left + (right - left) / 2;
    19             // In this case, the array is sorted.
    20             // 这一句很重要,因为我们移除一些元素后,可能会使整个数组变得有序...
    21             if (num[left] < num[right]) {
    22                 return num[left];
    23             }
    24             
    25             // left side is sorted. CUT the left side.
    26             if (num[mid] > num[left]) {
    27                 left = mid;
    28             // left side is unsorted, right side is sorted. CUT the right side.
    29             } else if (num[mid] < num[left]) {
    30                 right = mid;
    31             } else {
    32                 left++;
    33             }
    34         }
    35         
    36         return Math.min(num[left], num[right]);        
    37     }
    38 }
    View Code

    2015.1.1 Redo:

     1 public class Solution {
     2     public int findMin(int[] num) {
     3         if (num == null || num.length == 0) {
     4             return 0;
     5         }
     6         
     7         int l = 0;
     8         int r = num.length - 1;
     9 
    10         while (l < r - 1) {
    11             int mid = l + (r - l) / 2;
    12             
    13             // The array is sorted.    
    14             if (num[l] < num[r]) {
    15                 return num[l];
    16             }
    17             
    18             if (num[mid] < num[r]) {
    19                 r = mid;
    20             // left side is sorted. discard the left side.    
    21             } else if (num[mid] > num[l]) {
    22                 l = mid;
    23             } else {
    24                 l++;
    25             }
    26         }
    27         
    28         return Math.min(num[l], num[r]);
    29     }
    30 }
    View Code

    GitHub Code:

    https://github.com/yuzhangcmu/LeetCode_algorithm/blob/master/binarySearch/FindMin2.java

  • 相关阅读:
    程序猿财务自由之路·规划篇
    如何教女友学编程?
    粤港澳大湾区9城最新购房政策一览
    一个漂亮妹子的美团面试经历,4轮2小时,成功拿到Offer
    在北京的互联网公司工作多少年可以买房?
    这六个 MySQL 死锁案例,能让你理解死锁的原因!
    阿里双11:「线上全链路压测」完整经验分享
    千亿级公司低代码平台的测试体系介绍
    Weblogic
    30分钟?不需要,轻松读懂IL
  • 原文地址:https://www.cnblogs.com/yuzhangcmu/p/4049117.html
Copyright © 2011-2022 走看看