百度笔试题----最小不重复数

给定一个任意数,找出比这个数大的最小不重复数(不重复数是指:这个数的相邻两位不同如:1231为不重复数,而1233为重复数)。

其实这个题目,看起来挺简单的,我只要从这个数开始一直向上找,总会找到吧。。确实,但是如果我给你一个特别大的数呢,比如:111111111,这就傻了,那要遍历多少个数啊!所以这样做很不现实。那我们就来分析下吧。先找几个用例看看:

123------------>124

111------------>120

999------------>1010

8989------------>9010


通过分析,我们很容易想到,从前往后遍历 ,看是否有相邻的元素相同,如果有,那么要分成两种情况:相同的数为9和不为9。如果不为9,那么直接将第二位+1,后面的就变成010101....。;如果为9,那么从第一个9开始就要变成010101,而且还存在进位,相当于加上100000(此时的情况为:*99_ _ _)如果没有,那么直接+1就可以了?(8989这种特例)这还不够,还必须对这个新的数进行判断是否是重复数,如果是就执行上述代码,如果不是,就返回这个数。


#include<iostream>
using namespace std;

bool isOK=false;//如果是重复数,通过处理后肯定可以直接输出。否则还必须进行下一轮的处理。
bool isFirstDeal=true;//是否是第一次处理这个新输入的数
int deal(int input)
{
	bool isChange=false;//判断是否是重复数
	bool isOverFlow=false;
	char* temp=new char[12];
	memset(temp,0,12);
	itoa(input,temp,10);		
	int length=strlen(temp);
	int i=1;
	while(i<length)
	{
		if(temp[i]==temp[i-1])
		{
			isChange=true;
			if(temp[i]!='9')
			{
				temp[i]+=1;
				break;
			}
			else
			{
				isOverFlow=true;
				break;
			}
		}
		++i;
	}
	int result;
	if(isChange)
	{
		
		if(!isOverFlow)//重复9溢出
		{
			if(i+1<length)
				temp[i+1]='0';	
			int j=i+2;
			for(j;j<length;++j)
			{
				temp[j]=(temp[j-1]-'0'+1)%2+'0';
			}
			result=atoi(temp);
		}
		else
		{
			temp[i-1]='0';
			int j=i;
			for(j;j<length;++j)
			{
				temp[j]=(temp[j-1]-'0'+1)%2+'0';
			}
			int base=1;
			for(j=i-1;j<length;++j)
				base*=10;
			result=atoi(temp)+base;
		}
		isOK=true;//因为这个是重复数,已经处理过了,可以直接输出
	}
	else 
	{
		if(isFirstDeal)
			result=input+1;
		else
			result=input;
		isOK=false;//因为不是重复数,虽然已经处理过一遍(加了1),但还是需要处理第二次,防止加1之后的数为重复数。
	}
	delete[] temp;
	return result;
}

void main()
{
	int input;
	while(cin>>input)
	{
		int result=deal(input);
		if(isOK)
			cout<<"输出: "<<result<<endl;
		else
		{
			if(isFirstDeal)
			{
				isFirstDeal=false;
				result=deal(result);
			}
			cout<<"输出: "<<result<<endl;
		}
		isOK=false;
		isFirstDeal=true;//返回初始状态
	}
}
百度笔试题----最小不重复数_第1张图片

你可能感兴趣的:(百度笔试题----最小不重复数)