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. cookingk配置项中的chunk:true含义

    学习cooking,查看中文文档,发现有个配置chunk: true, 不明白具体含义,于是根据注释,找到了相关代码, 即chunk: true等同于以下代码: var webpackConfig = ...

  2. 如何为 setTimeout() 方法传参

    现有如下JavaScript代码: function printApple(apple){ console.log(apple, "is a kind of healthy fruit&qu ...

  3. linux下vi命令笔记

    vim 编辑器 全屏编辑器 模式化编辑器 vi:Visual Interfacevim:VI iMproved vi增强版vi模式:    编辑模式(命令模式)(默认处于编辑模式)        Ct ...

  4. 关于EF查询表里的部分字段

    这个在项目中用到了,在网上找了一下才找到,留下来以后自已使用. List<UniversalInfo> list =new List<UniversalInfo>(); lis ...

  5. 关于一些Android冷知识

    1. 在Android4.0以后,EditText就由以前的输入框变成了一条划线的输入方式,如需要变为老版本的,只需在layout里面引入代码: android:background="@a ...

  6. java.lang.reflection打印一个类的全部信息

    package com.ljy.chapter5; import java.lang.reflect.Constructor; import java.lang.reflect.Field; impo ...

  7. 计算机网络基础_01IP地址

    1,IP地址组成和分级分级 IP地址=网络地址+主机地址 32位,4段组成 A:最高位是0 ,1个字节的网络地址,3个字节的主机地址 B:最高位是10,2个字节的网络地址,2个字节的主机地址 C:最高 ...

  8. 服务器上搭建spark开发环境

    1.安装相应的软件 (1)安装jdk 下载地址:http://www.Oracle.com/technetwork/java/javase/downloads/index.html (2)安装scal ...

  9. hdu 3308

    终于A了,我好想砍人,虽然这是一道基础的区间合并.但是这错误我也是醉了. 错误我表在注释里. 题目意思不多说,sha崽题目出的很简洁. #include <iostream>#includ ...

  10. WPF WebBrowser 不可见问题的解析[转]

    问题概述: 1.在Xaml中加入WebBrowser(不论是WPF中的控件,还是Winform中的控件) 2.设置Window Background="Transparent" A ...