Find Minimum in Rotated Sorted Array


Question Solution
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.

You may assume no duplicate exists in the array.

SOLUTION 1:
这个题目trick的地方在于,它的旋转pivot次数未知。所以有可能它转了一圈又转回了原处

所以我们代码要处理2种情况:
我们还是用二分法来做。比起全部扫一次,二分法可以做到LogN的复杂度。
1. Sorted

这种情况简单,先计算出mid的值,如果它处在左右的中间,证明这个数列是正常的sorted,直接返回左边。

2. 中间断开(也就是说旋转过)
我们的目的是要找出存在断口的地方。所以我们可以每次求一下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.

注意,丢掉半边时,mid不可以丢掉,因为有可能mid就是答案。
例子: 3, 1, 2 的时候,3, 1是逆序,1, 2是正序,如果你扔掉1,2你就丢掉了答案。

  1. // Solution 1:
  2. public int findMin1(int[] num) {
  3. if (num == null || num.length == 0) {
  4. return 0;
  5. }
  6.  
  7. if (num.length == 1) {
  8. return num[0];
  9. }
  10.  
  11. // 至少有2个元素,才有讨论的价值
  12. int l = 0;
  13. int r = num.length - 1;
  14.  
  15. while (l < r) {
  16. int mid = l + (r - l)/2;
  17. // Means that there is no rotate.
  18. if (num[mid] >= num[l] && num[mid] <= num[r]) {
  19. return num[0];
  20. }
  21.  
  22. // rotate > 0的情况
  23. if (l == r - 1) {
  24. // 当只余下2个元素的时候,这里是断点,右边的是小值
  25. return num[r];
  26. }
  27.  
  28. if (num[mid] >= num[l]) {
  29. // The left side is sorted. Discard left.
  30. l = mid;
  31. } else {
  32. // The right side is sorted.
  33. r = mid;
  34. }
  35. }
  36.  
  37. return 0;
  38. }

SOLUTION 2:

采用九章算法的二分法模板来解:

这个模板最大的好处是 while(left < right - 1) 这样的话,终止时就一定是left = right - 1,而且mid 一直会是在中间,不会靠到left去。判断起来会相当
便利。
常见bug:

// bug 1: should not use l = m + 1 and r = m - 1.
// this may discard the minumul value.

A example: 3, 1, 2.

  1. // solution 2:
  2. public int findMin(int[] A) {
  3. if (A == null || A.length == 0) {
  4. return 0;
  5. }
  6.  
  7. if (A.length == 1) {
  8. return A[0];
  9. } else if (A.length == 2) {
  10. return Math.min(A[0], A[1]);
  11. }
  12.  
  13. // 至少有3个元素,才有讨论的价值
  14. int l = 0;
  15. int r = A.length - 1;
  16.  
  17. while (l < r - 1) {
  18. int m = l + (r - l) / 2;
  19.  
  20. // means that there is no rotate.
  21. if (A[m] < A[r] && A[m] > A[l]) {
  22. return A[0];
  23. }
  24.  
  25. // left side is sorted.
  26. if (A[m] > A[l]) {
  27. l = m;
  28. } else {
  29. r = m;
  30. }
  31. }
  32.  
  33. return A[r];
  34. }
 
所以以后一定要多使用模板化的编程 ,特别是这里总结的二分法模板:
  1. while (l < r - 1) {
  2. int m = l + (r - l) / 2;
  3.  
  4. // means that there is no rotate.
  5. ... 这里添加各种退出条件,比如找到了目标值等
  6. // left side is sorted.
  7. if (A[m] > A[l]) {
  8. l = m;
  9. } else {
  10. r = m;
  11. }
  12. }

SOLUTION 3:

在解答2的基础之上,可以把判断是否rotated的statement去掉,然后每次丢弃有序数列时,先丢弃右边的。这样子即使是从未rotated的也没有关系,因为一直是丢右边的

直到余下左边最后2个。

  1. public int findMin(int[] num) {
  2. if (num == null || num.length == 0) {
  3. return 0;
  4. }
  5.  
  6. int l = 0;
  7. int r = num.length - 1;
  8.  
  9. while (l < r - 1) {
  10. int m = l + (r - l) / 2;
  11.  
  12. if (num[m] < num[r]) {
  13. // bug 1: should not use l = m + 1 and r = m - 1.
  14. // this may discard the minumul value.
  15. r = m;
  16. } else {
  17. l = m;
  18. }
  19. }
  20.  
  21. return Math.min(num[l], num[r]);
  22. }

SOLUTION 4:

在解答3的基础之上先,预判断是不是旋转过,这样如果没有旋转我们可以直接把解算出即可。

  1. public int findMin(int[] num) {
  2. if (num == null || num.length == ) {
  3. return ;
  4. }
  5.  
  6. int l = ;
  7. int r = num.length - ;
  8.  
  9. if (num[l] < num[r]) {
  10. return num[l];
  11. }
  12.  
  13. while (l < r - ) {
  14. int m = l + (r - l) / ;
  15.  
  16. if (num[m] < num[r]) {
  17. // bug 1: should not use l = m + 1 and r = m - 1.
  18. // this may discard the minumul value.
  19. r = m;
  20. } else {
  21. l = m;
  22. }
  23. }
  24.  
  25. return Math.min(num[l], num[r]);
  26. }

FOLLOW UP:

LeetCode 新题: Find Minimum in Rotated Sorted Array II 解题报告-二分法模板解法

GitHub:

GitHub代码链接

LeetCode 新题: Find Minimum in Rotated Sorted Array 解题报告-二分法模板解法的更多相关文章

  1. 【LeetCode】153. Find Minimum in Rotated Sorted Array 解题报告(Python)

    [LeetCode]153. Find Minimum in Rotated Sorted Array 解题报告(Python) 标签: LeetCode 题目地址:https://leetcode. ...

  2. LeetCode 新题: Find Minimum in Rotated Sorted Array II 解题报告-二分法模板解法

    Find Minimum in Rotated Sorted Array II Follow up for "Find Minimum in Rotated Sorted Array&quo ...

  3. 【LeetCode】Find Minimum in Rotated Sorted Array 解题报告

    今天看到LeetCode OJ题目下方多了"Show Tags"功能.我觉着挺好,方便刚開始学习的人分类练习.同一时候也是解题时的思路提示. [题目] Suppose a sort ...

  4. LeetCode: Search in Rotated Sorted Array 解题报告

    Search in Rotated Sorted Array Suppose a sorted array is rotated at some pivot unknown to you before ...

  5. 【LeetCode】154. Find Minimum in Rotated Sorted Array II 解题报告(Python)

    [LeetCode]154. Find Minimum in Rotated Sorted Array II 解题报告(Python) 标签: LeetCode 题目地址:https://leetco ...

  6. 【刷题-LeetCode】154 Find Minimum in Rotated Sorted Array II

    Find Minimum in Rotated Sorted Array II Suppose an array sorted in ascending order is rotated at som ...

  7. 【刷题-LeetCode】153 Find Minimum in Rotated Sorted Array

    Find Minimum in Rotated Sorted Array Suppose an array sorted in ascending order is rotated at some p ...

  8. 【LeetCode】153. Find Minimum in Rotated Sorted Array (3 solutions)

    Find Minimum in Rotated Sorted Array Suppose a sorted array is rotated at some pivot unknown to you ...

  9. LeetCode OJ 154. Find Minimum in Rotated Sorted Array II

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

随机推荐

  1. 〖Windows〗zigbee实验之cygwin编译TestSimpleMac并测试通信

    1. 开发环境及工具: 1) cygwin安装包下载地址:cygwin-files.zip    >>安装时选择本地目录(Select local Package directory),其 ...

  2. webservice系统学习笔记6-使用soap的header传递消息

    1.显示的使用soap的header传递消息(不推荐使用,会破坏正常的代码结构,推荐使用handler处理) @WebResult(name="deleteResult") pub ...

  3. 身份证查询API

    # -*- coding: utf-8 -*- #python 27 #xiaodeng #http://apistore.baidu.com/apiworks/servicedetail/113.h ...

  4. java 生成可执行jar包

    jar -cvfm my.jar [配置主函数入口文件] [包] Main-Class: 包名.类名   注意“:”后边有一个空格,类名后边要有回车换行

  5. 使用 Feed43

    1.打开 Feed43 2.将标题.链接,时间等变化的字段删去用 {%} 代替.将固定且多余的字段删去用 {*} 代替.注意,源码中有换行的地方均需要添加{*} . 3.活学活用

  6. Nginx的HTTPS 301重定向到另一个TLD(托管在同一服务器上)没有显示出SSL警告

    我自己 example.com, .com.au, .net, .net.au, ... (8 in total). 我想所有的这些顶级域名以301的域名重定向到安全.COM域 https://www ...

  7. Oracle 11g的Deferred Segment Creation

    本篇主要介绍Oracle 11g中推出的“延迟段创建”(Deferred Segment Creation)特性,以及当我们使用这种特性时,需要注意的问题. 1)Deferred Segment Cr ...

  8. java多线程学习--java.util.concurrent

    CountDownLatch,api 文档:http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/CountDownLatch.h ...

  9. SQL SERVER 2005允许自定义聚合函数-表中字符串分组连接

    不多说了,说明后面是完整的代码,用来将字符串型的字段的各行的值拼成一个大字符串,也就是通常所说的Concat 例如有如下表dict  ID  NAME  CATEGORY  1 RED  COLOR  ...

  10. PO_PO接受入库时的接受方式详解(概念)

    2014-06-03 Created By BaoXinjian