[LeetCode#154]Find Minimum in Rotated Sorted Array II
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的更多相关文章
- [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 ...
- [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. ...
- 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 ...
- 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 ...
- 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. ( ...
- 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. ( ...
- 【LeetCode】154. Find Minimum in Rotated Sorted Array II 解题报告(Python)
[LeetCode]154. Find Minimum in Rotated Sorted Array II 解题报告(Python) 标签: LeetCode 题目地址:https://leetco ...
- 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 ...
- 【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 ...
随机推荐
- java中关于public class
在编写类的时候可以使用两种方式定义类: public class定义类: class定义类: 1,如果一个类声明的时候使用了public class进行了声明,则类名称必须与文件名称完 ...
- 论前端css初始化的重要性
新手,求喷,刚刚知道每个浏览器都有对 标签的初始化,就造成我们网站开发者开发的web程序,会在不同的网站上有不同的样式风格,这给用户带来了很不好的体验,这也是浏览器本身的原因造成的,这时候,我们不可能 ...
- JavaScript Math对象
Math对象是JavaScript的一个固有对象,其作用是执行常见的算数任务.该对象的使用并不是像Date,Array对象使用 new关键字来得到对象,而是直接 Math.[{property|met ...
- string.Join和Reverse的简单使用示例
String.Join 方法 (String, String[]) 串联字符串数组的所有元素,其中在每个元素之间使用指定的分隔符. 例如,如果 separator 为“,”且 value 的元素为“a ...
- Windows的计划任务
阅读目录 一:什么是Windows的计划任务? 二:如何设置计划任务 三:高级设置计划任务 一:什么是Windows的计划任务? 在日常的工作中,我们都有一些固定的或临时性的工作,而每次在爱机前一坐, ...
- 关于ios8斯坦福公开课第二课
在这个课程中,我们遇到了这样的代码 @IBAction func oprate(sender: UIButton) { let opration = sender.currentTitle! if u ...
- 寒哥教你学 iOS - 经验漫谈(转)
转自http://www.cocoachina.com/ios/20150907/13339.html 本篇文章主要讲解 4个问题 load妙用 aop面向切面编程 NSNumber Or Int @ ...
- 64位 CentOS NDK 编译 FFMPEG
64位 CentOS NDK 编译 FFMPEG 一. 参考文章: http://www.cnblogs.com/baopu/p/4733029.html http://www.c ...
- POJ 1286 Necklaces of Beads (Burnside定理,有限制型)
题目链接:http://vjudge.net/problem/viewProblem.action?id=11117 就是利用每种等价情形算出置换节之后算组合数 #include <stdio. ...
- PHP框架_Smarty
目录 1.环境搭建 2.基本配置 3.Smarty变量调节器 4.Smarty条件判断 5.Smarty的循环 6.Smarty模板的引用 7.Smarty类与对象的赋值与引用 8.smarty函数插 ...