document.write('
方法一:蛮力法
 最容易想到的方法就是对这个给定的数加1,然后判断这个数是不是“不重复数”,如果不是,那
么继续加1,直到找到“不重复数”为止。显然这种方法的效率非常低下。
 方法二:从右到左的贪心法
 例如给定数字11099,首先对这个数字加1,变为11000,接着从右向左找出第一对重复的数字
00,对这个数字加1,变为11001,继续从右向左找出下一对重复的数00,将其加1,同时把这一位
往后的数字变为0101…串(当某个数字自增后,只有把后面的数字变成0101…,才是最小的不重复数
字),这个数字变为11010,接着采用同样的方法,11010->12010就可以得到满足条件的数。
 需要特别注意的是当对第i个数进行加1操作后可能会导致第i个数与第i+1个数相等,因此,需要处
理这种特殊情况,下图以99020为例介绍处理方法。
\"360截图20190813170311615.jpg\"
 (1)把数字加1并转换为字符串。
 (2)从右到左找到第一组重复的数99(数组下标为i=2),然后把99加1,变为100,然后把后面的字
符变为0101…串。得到100010。
 (3)由于执行步骤(2)后对下标为2的值进行了修改,导致它与下标为i=3的值相同,因此,需要对i
自增变为i=3,接着从i=3开始从右向左找出下一组重复的数字00,对00加1变为01,后面的字符变
为0101…串,得到100101。
 (4)由于下标为i=3与i+1=4的值不同,因此,可以从i-1=2的位置开始从右向左找出下一组重复的
数字00,对其加1就可以得到满足条件的最小的“不重复数”。
 根据这个思路给出实现方法如下:
 1)对给定的数加1。
 2)循环执行如下操作:对给定的数从右向左找出第一对重复的数(下标为i),对这个数字加1,然后
把这个数字后面的数变为0101…得到新的数。如果操作结束后下标为i的值等于下标为i+1的值,那
么对i进行自增,否则对i进行自减;然后从下标为i开始从右向左重复执行步骤2),直到这个数
是“不重复数”为止。
 实现代码如下:
 """
 方法功能: 处理数字相加的进位
 输入参数: num为字符数组, pos为进行加1操作对应的下标位置
 """
 def carry(num,pos):
 while pos>0:
 if int(num[pos])>9:
 num[pos]=\'0\'
 num[pos-1]=str(int(num[pos-1])+1)
 pos-=1
 """
 方法功能: 获取大于n的最小不重复数
 输入参数: n为正整数
 返回值: 大于n的最小不重复数
 """
 def findMinNonDupNum(n):
 count=0 #用来记录循环次数
 nChar=list(str(n+1))
 ch=[None]*(len(nChar)+2)
 ch[0]=\'0\'
 ch[len(ch)-1]=\'0\'
 i=0
 while i<len(nChar):
 ch[i+1]=nChar[i]
 i+=1
 lens=len(ch)
 i=lens-2 #从右向左遍历
 while i>0:
 count+=1
 if ch[i-1]==ch[i]:
 ch[i]=str(int(ch[i])+1) #末尾数字加1
 carry(ch,i) #处理进位
 #把下标为i后面的字符串变为0101…串
 j=i+1
 while j<lens:
 if (j-i)%2==1:
 ch[j]=0\'
 else:
 ch[j]=\'1\'
 j+=1
 #第i位加1后,可能会与第i+1位相等
 i+=1
 else:
 i-=1
 print "循环次数为:"+str(count)
 return int(".join(ch))
 
 if __name__=="__main__":
 print findMinNonDupNum(23345)
 print findMinNonDupNum(1101010)
 print findMinNonDupNum(99010)
 print findMinNonDupNum(8989)
 程序的运行结果为:
 循环次数为:7
 23401
 循环次数为:11
 1201010
 循环次数为:13
 101010
 循环次数为:10
 9010
 方法三:从左到右的贪心法
 与方法二类似,只不过是从左到右开始遍历,如果碰到重复的数字,那么把其加1,后面的数字变
成0101…串。实现代码如下:
 """
 方法功能: 处理数字相加的进位
 输入参数: num为字符数组, pos为进行加1操作对应的下标位置
 """
 def carry(num,pos):
 while pos>0:
 if int(num[pos])>9:
 num[pos]=\'0\'
 num[pos-1]=str(int(num[pos-1])+1)
 pos-=1
 
 """
 方法功能: 获取大于n的最小不重复数
 输入参数: n为正整数
 返回值: 大于n的最小不重复数
 """
 def findMinNonDupNum(n):
 count=0 #用来记录循环次数
 nChar=list(str(n+1))
 ch=[None]*(len(nChar)+1)
 ch[0]=\'0\'
 i=0
 while i<len(nChar):
 ch[i+1]=nChar[i]
 i+=1
 lens=len(ch)
 i=2 #从左向右遍历
 while i<lens:
 count+=1
 if ch[i-1]==ch[i]:
 ch[i]=str(int(ch[i])+1) #末尾数字加1
 carry(ch,i) #处理进位
 #把下标为i后面的字符串变为0101...串
 j=i+1
 while j<lens:
 if(j-i)%2==1:
 ch[j]=\'0\'
 else:
 ch[j]=\'1\'
 j+=1
 else:
 i+=1
 print "循环次数为: "+str(count)
 return int(".join(ch))
 
 if __name__=="__main__":
 print findMinNonDupNum(23345)
 print findMinNonDupNum(1101010)
 print findMinNonDupNum(99010)
 print findMinNonDupNum(8989)
 显然,方法三循环的次数少于方法二,因此,方法三的性能要优于方法二。

 

');