# -*- coding: utf-8 -*-
'''
Python程序员面试算法宝典---解题总结: 第6章 基本数字运算 6.11 如何找到最小的不重复数
题目:
给定任意一个正整数,求比这个数大且最小的不重复数,不重复数的
含义是相邻两位不同,例如1101是重复数,而1201是不重复数。
分析:
关键:
1 书上解法
从右到左的贪心法。
从右向左找出第一对重复的数字,把这个数字中这对重复数字的后面的
那一位加1,继续从右向左找出下一对重复的数,将其加1,
同时把这一位后面的数字变成0101...(因为前面变大,后面必须是最小的,
才能保证所求的是最小的非重复数字)
算法:
步骤1: 对给定的数+1
步骤2: 循环执行如下操作:
对给定的数从右向左找出第一对重复的数(下标为i),
对这个数字加1,然后把这个数字后面的数变为0101...
得到新的数。
如果操作后下标为i的值等于下标为i+1的值,那么对i进行
自增;否则对i进行自减;然后从下标为i开始从右向左重复执行
步骤2,直到这个数是非重复数为止。
总结;
每次从右向左都找到第一对重复的数字,对这一对重复数字的后面一位
+1,并让其后面变成0101...
2 没有想到
是忘记从右向左的贪心法则。
找到第一对重复的数字(假设下标较大的为i),让这一对重复数字的后面那一位加1(考虑进位)
并令第i为后面的变成0101...因为你前面变大,后面就必须是最小的,从而才是最小非重复数字。
如果第i位数字和第i+1位数字相同,则i+1;否则i-1。
重复上述循环,直到i变为0.
参考:
Python程序员面试算法宝典
'''
def add(charList, i, addValue):
iCopy = i
passValue = addValue
while i >= 0:
curValue = int(ord(charList[i]) - ord('0'))
sumValue = curValue + passValue
newCurValue = sumValue % 10
charList[i] = str(newCurValue)
passValue = sumValue / 10
i -= 1
# 还需要将第i位后面的数字进行修改,修改为0101...
size = len(charList)
bitValue = 0
for j in range(iCopy+1, size):
charList[j] = str(bitValue)
if 0 == bitValue:
bitValue = 1
else:
bitValue = 0
# 如果最高位有进位,那么就需要在字符数组的最前面插入
isInsert = False
if passValue != 0:
charList.insert(0, str(passValue))
isInsert = True
return charList, isInsert
def findMinNonDupNum(n):
# 先将整数转换为字符列表
if n <= 0:
return -1
string = str(n)
charList = list(string)
size = len(charList)
i = size - 1
while i > 0:
# 判断如果当前位和前面一位的数字不同,则i直接减1
if charList[i] != charList[i-1]:
i -= 1
else:
# 说明当前位和前面一位相同,则将当前位的数字加1
# 加1的时候需要判定是否需要进位
charList, isInsert = add(charList, i, 1)
# 如果有进位了,那么原来的i就是现在的i+1
if isInsert:
i += 1
# 如果当前第i位和第i+1位相同,则i累加
if charList[i] == charList[i+1]:
i += 1
else:
i -= 1
temp = "".join(charList)
result = int(temp)
return result
def process():
num = 99020
result = findMinNonDupNum(num)
print result
num = 23345
result = findMinNonDupNum(num)
print result
num = 1101010
result = findMinNonDupNum(num)
print result
num = 99010
result = findMinNonDupNum(num)
print result
num = 8989
result = findMinNonDupNum(num)
print result
if __name__ == "__main__":
process()