[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 ...
随机推荐
- Five ways to maximize Java NIO and NIO.2--reference
Java NIO -- the New Input/Output API package-- was introduced with J2SE 1.4 in 2002. Java NIO's purp ...
- Android(java)学习笔记203:网页源码查看器(Handler消息机制)
1.项目框架图: 2.首先是布局文件activity_main.xml: <LinearLayout xmlns:android="http://schemas.android.com ...
- native跟volatile
native是告知编译器 该方法是其他语言实现的 比如C 呵呵 private native void CoutSea();没有方法实现部分的 volatile是Java语言的关键字,用在变量的声明中 ...
- iBatis 的修改一个实体
Student.xml <update id="updateStudent" parameterClass="Student" > UPDATE S ...
- The performance between the 'normal' operation and the 'shift' operation.
First, I gonna post my test result with some code: //test the peformance of the <normal operation ...
- Premature optimization is the root of all evil.
For all of we programmers,we should always remember that "Premature optimization is the root of ...
- hadoop-0.20-集群搭建___实体机通过SSH访问基于VM安装的Linux
不得不说LZ在最开始搭建hadoop的时候,由于VM中的网段配置和本地IP地址没有配置好, 所以一直都在使用 VM的共享文件夹的功能, 以至于集群搭建好之后,只有namenode主机可以实现共享的功能 ...
- iOS中JavaScript和OC交互
转载自:http://www.devzeng.com/blog/ios-uiwebview-interaction-with-javascript.html 还可参考的文章:http://blog.c ...
- linux常用命令(查看某些软件是否已安装)
查看imap是否已安装 rpm -qa | grep imap 以下为未安装的情形: 检查是否已安装sendmail: rpm -qa | grep sendmail 以下为已安装的返回:
- AppiumDriver 运行app启动基本参数
记录一下 DesiredCapabilities capabilities = new DesiredCapabilities(); capabilities.setCapability(Mobile ...