Python程序员面试算法宝典---解题总结: 第6章 基本数字运算 6.11 如何找到最小的不重复数

# -*- 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()

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值