算法笔试题练习(二)

1.求比这个数大且最小的“不重复数”

今天看到david的百度2014校招笔试题目题解(链接

题目是这样的:1、给定任意一个正整数,求比这个数大且最小的“不重复数”,“不重复数”的含义是相邻两位不相同,例如1101是重复数,而1201是不重复数。(15分)

里面给出了一种解决方案,如下:

  1、因为可以直接定位到“重复”的数位那里,比如12344,我们可以直接定位到个位数4和十位数4上面,然后在低位数(这里就是个位数)上加1即可,事实上,不是如此简单,假设是对整数12199呢?还能简单的加1操作吗,加1之后结果为12200,那结果显然是错的,当然这也是可以处理的,处理方法就是把12200继续拿到循环去判断是不是“非重复数”;

  2、这里又产生一个问题,因为“重复“的数位可能不止一对,有可能有多对,比如整数11233,定位“33”之后变为“34”,定位“11”之后变为“12”,结果就是12234。又有重复的地方,就是“22”。继续拿到循环去重复;

  3、还有要注意的是,你的程序设计,是如何存储数位的值的,是一个一个数位的值求出来呢?还是像我这样设置一个前后索引?每个数位取值,程序会变得繁琐复杂,不易读懂,如果是设置前后索引,则要注意程序退出循环的条件!

  4、对于存在多对“重复”数位的正整数,数位“重复”的定位和变换,是从高位到低位,还是从低位到高位呢?正确的应该是从高位到低位,这与我们的程序设计也带来了不便。

对于第二个问题,因为是大于某数A最小的不重复数,所以我们可以考虑将数字转换为字符串,按数字的高位->低位处理(按david的意思,c中类型转换比较麻烦)其实david多虑了,对于像大数运算、进制转换等问题都是讲数字转换为字符串处理的,一方面是考虑溢出的问题,另一方面有时运行效率会有提高。

思路:

1.初始化A数字并+1;

2.将数字A转换为字符串,判断字符串是否是不重复数,如果是重复数,返回第二次重复的下标赋值给flag,否则返回-1;

3.循环字符串,将第二次出现重复数后面都置0,将第二次出现重复的数所对应的位值+1,然后重复第2步;

4.如果flag值为-1,结束循环;

代码是python实现的:

def checknum(num):
    sNum=str(num)
    nlen=len(sNum)
    for i in range(1,nlen):
        if(sNum[i-1]==sNum[i]):
            return i
    return -1
def getnum(num):
    num+=1
    flag=checknum(num)
    while flag<>-1:
        nlen=len(str(num))
        mi=(nlen-flag-1)
        if(nlen-flag)>1:
            num=num-num%(10**mi)
        num+=(10**mi)
        flag=checknum1(num)return num
output:
getnum(123444)  123450
getnum(199990) 201010
getnum(99990) 101010

以上是需要类型转换的方法,如果用c来实现而不用类型转换的话,只有累计除10^位下标后求模循环了,后续给出c的代码...

原文地址:https://www.cnblogs.com/keily/p/3356936.html