[LeetCode] Find Minimum in Rotated Sorted Array II (包含递增和递减旋转,含有重复数字)

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

这个是接着上一篇的:http://blog.csdn.net/lgd_yyf/article/details/40536943

针对原题中有重复数字的情况,在上一篇递归解法的基础之上,稍作修改即可。

注意到,我们在选择下一次递归的位置时,可以发现,在无重复数字时,只有两种情况:

1、num[mid] > Math.max(num[start], num[end])

2、num[mid] < Math.min(num[start], num[end])

但是包含重复数字时,情况就不一样了,有可能出现num[mid]和其中一个相等的情况,故需要分类讨论。在分类之前,对数组做如下处理:若rotate的位置恰好出现重复数字当中,则将后面的重复数字去掉(这一点在后面分类的时候,将起到作用)。下面开始分类:(函数为 public int searchMin(int[] num, int start, int end) ;)

int mid=(start+end)/2;

1、num[mid] >= num[start] && num[mid] <= num[end]  示例:[ 4,3,1,1,1] 或 [3,4,1,1,1] 或 [1,1,1,1,1]

若都取等号,则说明数组都是同一数字,无论何种递归,最后都会返回正确值;

若 num[mid] == num[start],则 num[mid] < num[end] ,根据上篇所讲的取 最小值和最大值原理,

 return searchMin(num, mid, end);

同理,若 num[mid] == num[end],则 

 return searchMin(num, mid, end);

2、num[mid] <= num[start] && num[mid] >= num[end] 示例:[ 1,1,14,3] 或 [1,1,1,3,4] 

若 num[mid] == num[start],则 num[mid] > num[end] ,根据上篇所讲的取 最小值和最大值原理,

 return searchMin(num, mid, end);

同理,若 num[mid] == num[end],则 

 return searchMin(num, mid, end);

3、num[mid] >= num[start] && num[mid] >= num[end] 示例:[ 4,3,6,6,5] 或 [3,4,5,5,1] 

4、num[mid] <= num[start] && num[mid] <= num[end]  示例: [ 3,4,1,1,2] 或 [4,3,1,6,5] 

3、4情况就是和上一题中的原理一样,这里不再赘述。

事实上,在判断的时候 用 if-else if-else对1、2、3、4顺序判断下来 ,3、4中的等号情况是不会出现的。

实现如下:

public int findMin(int[] num) {
	int len = num.length;
	// 去掉末尾和开头重复的部分
	if (num[0] == num[len - 1]) {
	    while (len >= 2 && num[len - 2] == num[len - 1])
	         len--;
	    len--;
	}
	if (len <= 1) {
	    return num[0];
	}
	return searchMin(num, 0, len - 1);
}

public int searchMin(int[] num, int start, int end) {
	if (start + 1 == end) {
	    return Math.min(num[start], num[end]);
	}

	int mid = (start + end) / 2;
	if (num[mid] >= num[start] && num[mid] <= num[end]) {
	    if (num[mid] == num[start])
	        return searchMin(num, mid, end);
	    else
	        return searchMin(num, start, mid);
	} else if (num[mid] <= num[start] && num[mid] >= num[end]) {
	    if (num[mid] == num[end])
	        return searchMin(num, start, mid);
	    else
	        return searchMin(num, mid, end);
	} else if (num[mid] >= num[start] && num[mid] >= num[end]) {
	    if (num[start] > num[end])
	        return searchMin(num, mid, end);
	    else
	        return searchMin(num, start, mid);
	} else {
	    if (num[start] > num[end])
	        return searchMin(num, start, mid);
	    else
	        return searchMin(num, mid, end);
	}
}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值