二分查找进阶——循环有序数组查找再进阶——循环有序重复数组查找

就在昨天才刚刚写了一篇关于循环有序数组查找的函数:http://blog.csdn.net/qq_33724710/article/details/51200889

今天又发现了这道题的升级版微笑,迫不及待的拿来和大家分享(依旧来自LeetCode):

Remove Duplicates from Sorted Array II

Follow up for "Remove Duplicates":
What if duplicates are allowed at most twice?

For example,
Given sorted array nums = [1,1,1,2,2,3],

Your function should return length = 5, with the first five elements of nums being 1, 1, 2, 2 and 3. It doesn't matter what you leave beyond the new length.

有了昨天解题的思想,这道题其实无非就是多了个重复的因素:

分析(《LeetCode-cpp》):

允许重复元素,那么我们上一题的假设nums[mid] >= nums[first],则[first, num]递增的假设就不能成立了,比如1,3,1,1,1

如果nums[mid] >= nums[first]不能确定递增,那就把它拆分成两个条件:

1、若nums[mid] >= nums[first],则区间[first,mid]一定递增

2、若nums[mid] == nums[first],那就first++,往下一步看即可

接下来就让我们来分析下代码:

/* 
 * leetcode, Search in Rotated Sorted Array II
 * Follow up for "Search in Rotated Sorted Array":
 * What if duplicates are allowed?
 * Would this affect the run-time complexity? How and why?
 * Write a function to determine if a given target is in the array.
 */
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>

#define true 1
#define false 0
typedef int bool;

bool search(int* nums, int numsSize, int target) {
	int first = 0;
	int last = numsSize - 1;
	/*
	 * 与无重复的相比,不同的是,当 nums[first] <= nums[mid] 时,不能以此判断[first,mid]是递增的
	 * 所以当 nums[first] = nums[mid] 时,++first,跳过一个重复的数,继续循环判断,
	 * 直到nums[first] != nums[mid],此时的情况就与无重复的有序数组相同了
	 */
	while (first <= last) {
		int mid = (last - first) / 2 + first;
		if (*(nums + mid) == target)
			return true;
		else if (*(nums + first) < *(nums + mid)) {
			if (*(nums + first) <= target && *(nums + mid) > target)
				last = mid - 1;
			else
				first = mid + 1;
		}
		else if (*(nums + first) > *(nums + mid)) {
			if (*(nums + last) >= target && *(nums + mid) < target)
				first = mid + 1;
			else
				last = mid - 1;
		}
		else {    //跳过一个重复的数
			++first;
		}
	}
	return false;
}
int main()
{
	int arr[] = { 1, 3, 1, 1, 1 };
	int sz = sizeof(arr) / sizeof(arr[0]);

	bool ret = search(arr, sz, 1);
	if (ret == true)
		printf("true\n");
	else
		printf("false\n");
	system("pause");
	return 0;
}
有了上一题的思路,这道题是不是也不难呢?


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Fireplusplus

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值