The question:

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.

My first ugly solution:

public class Solution {
public int findMin(int[] num) {
if (num == null || num.length == 0)
return -1; int low = 0;
int high = num.length - 1;
int mid = -1; while (low < high) {
mid = (low + high) / 2;
if (num[low] == num[mid] && low != mid) {
low ++;
continue;
}
if (num[low] <= num[mid] && num[low] >= num[high])
low = mid + 1;
else
high = mid;
}
return num[low];
}
}

An improved analysis and solution.

This problem involves a very imporant skills in binary searching. It's very very tricky!!!
The idea behind this problem is not complex. It could be classified into following three cases:
1.A[mid] > A[low], we could discard this part, and search in the range[mid+1, high]
2.A[mid] < A[low], the mininum must be included in the first part range[low, mid]. Note the mid might be the answer, thus we could not discard it.
3.A[mid] == A[low]. In this case we could not distinguish which part may hold the anwser, but we need to proceed on. One solution is to move low pointer one step forward. We could discard A[low]. The resulting answer is:
public int findMin(int[] num) {
if (num == null || num.length == 0)
return -1;
int low = 0;
int high = num.length - 1;
int mid = -1;
while (low < high) {
mid = (low + high) / 2;
if (num[low] > num[mid])
high = mid;
else if (num[low] < num[mid])
low = mid + 1;
else
low ++;
}
return num[low];
}
However this solution has a very big pitfall!!!
Because the "divide operation" only return the interger part "mid = (low + high) / 2;", Before exiting from the loop, the low pointer could point to the same element with mid pointer. Consider following two cases:
1. 3 1
low : num[0] = 3, mid: num[0] = 3.
result in low++; return answer num[1] = 1. (The right answer) 2. 1 3
low : num[0] = 3, mid: num[0] = 3.
result in low++; return answer num[1] = 3. (The wrong answer) What a big problem!!!
An very elegant way to solve this problem. Using the same idea, we compare num[mid] and num[high], then update the solution into: while (low < high) {
mid = (low + high) / 2; if (num[mid] > num[high])
low = mid + 1;
else if (num[low] < num[mid])
high = mid;
else
high--;
}
return[low]; //note we reuturn[low] at here!!! If this fix works?
1. 3 1
high : num[0] = 1, mid: num[0] = 3.
result in high--; return answer num[0] = 1. (The right answer) 2. 1 3
high : num[1] = 3, mid: num[0] = 1.
result in high = mid = 0; return answer num[0] = 1. (The right answer) The reason is that: the high pointer would not point to the same element with mid. The invariant holds to the end!!!
iff high == mid, high must equal to low, since while (low < high), this case is impossible. Note:
The idea behind this method is that, this method could properly tackle the case when there are only two elements left. When only two elements left, the low pointer and mid pointer point to the same element. By comparing with the mid pointer, we could guarantee to reach the right answer by returing num[low].
if (num[mid] > num[high])
low = mid + 1;
else if (num[low] < num[mid])
high = mid;
else
high--;
When num[mid](low) > num[high], we move the low pointer to high. (low++), A[low] is the smaller.
When num[mid](low) < num[high], we keep low in the same position, A[low] is the smaller.

The improved solution:

public class Solution {
public int findMin(int[] num) {
if (num == null || num.length == 0)
return -1; int low = 0;
int high = num.length - 1;
int mid = -1; while (low < high) {
mid = (low + high) / 2; if (num[mid] > num[high])
low = mid + 1;
else if (num[low] < num[mid])
high = mid;
else
high--;
}
return num[low];
}
}

[LeetCode#154]Find Minimum in Rotated Sorted Array II的更多相关文章

  1. [LeetCode] 154. Find Minimum in Rotated Sorted Array II 寻找旋转有序数组的最小值 II

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

  2. [LeetCode] 154. Find Minimum in Rotated Sorted Array II 寻找旋转有序数组的最小值之二

      Suppose an array sorted in ascending order is rotated at some pivot unknown to you beforehand. (i. ...

  3. Java for LeetCode 154 Find Minimum in Rotated Sorted Array II

    Suppose a sorted array is rotated at some pivot unknown to you beforehand. (i.e., 0 1 2 4 5 6 7 migh ...

  4. leetcode 154. Find Minimum in Rotated Sorted Array II --------- java

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

  5. LeetCode 154. Find Minimum in Rotated Sorted Array II寻找旋转排序数组中的最小值 II (C++)

    题目: Suppose an array sorted in ascending order is rotated at some pivot unknown to you beforehand. ( ...

  6. LeetCode 154.Find Minimum in Rotated Sorted Array II(H)(P)

    题目: Suppose an array sorted in ascending order is rotated at some pivot unknown to you beforehand. ( ...

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

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

  8. leetcode 153. Find Minimum in Rotated Sorted Array 、154. Find Minimum in Rotated Sorted Array II 、33. Search in Rotated Sorted Array 、81. Search in Rotated Sorted Array II 、704. Binary Search

    这4个题都是针对旋转的排序数组.其中153.154是在旋转的排序数组中找最小值,33.81是在旋转的排序数组中找一个固定的值.且153和33都是没有重复数值的数组,154.81都是针对各自问题的版本1 ...

  9. 【LeetCode】154. Find Minimum in Rotated Sorted Array II (3 solutions)

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

随机推荐

  1. Java语言基础(二)

    Java语言基础(二) 一.变量续 (1).变量有明确的类型 (2).变量必须有声明,初始化以后才能使用 (3).变量有作用域,离开作用域后自动回收 变量作用域在块内有效 (4).在同一定义域中变量不 ...

  2. shell入门之expr的使用 分类: 学习笔记 linux ubuntu 2015-07-10 14:59 76人阅读 评论(1) 收藏

    在expr中加减乘除的使用,脚本如下: #!/bin/sh #a test about expr v1=`expr 5 + 6` echo "$v1" echo `expr 3 + ...

  3. 微信分享 分享icon和分享标题的简单设置

    前几天做的一个活动,用到微信分享功能,分享的icon.分享的标题和内容是自定义的.我上网查了一下,好多是注册微信公众号,使用微信api来实现的,注册微信号比较麻烦,最简单的方法就是 页面的title改 ...

  4. .net 学习路线感想

    从上到大学到现在工作,已经有六年多了,发现学习编程到以开发为工作也是一个挺长的过程的. 大学中,从c语言到java.C#到其他各种语言的学习,还有其他知识的学习如:数据库(oracle.sql Ser ...

  5. 安装Visual Studio 2010时提示"The location specified for the help content store is invalid or you do not have access to it".

    运行注册表: (运行->输入"regedit").在 HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Help\v1.0中,删除"Loc ...

  6. SGU 249.Matrix(Gray码)

    题意: 用0到2^(n+m-1)这2^(n+m-1)个数填在一个2^n*2^m的矩阵里,使得所有相邻的数的二进制表示只有一位不同. Solution: Gray码.对于第i行第j列的数,由i的Gray ...

  7. APP被Rejected 的各种原因翻译(转)

    原文:http://www.cnblogs.com/sell/archive/2013/02/16/2913341.html Terms and conditions(法律与条款) 1.1 As a ...

  8. apache-php安装mysql简单方法

    1.启用mysql功能,在php.ini中 extension=php_mysql.dll extension=php_mysqli.dll 2. 修改extension_dir = "ex ...

  9. 实用的透明背景mark图标

  10. Python爬虫第一步

    这只是记录一下自己学习爬虫的过程,可能少了些章法.我使用过的是Python3.x版本,IDE为Pycharm. 这里贴出代码集合,这一份代码也是以防自己以后忘记了什么,方便查阅. import req ...