百度14年校招笔试题:

n 为正整数,求比这个数大且最小的不重复数,重复数为相邻两位数字不相同

如: n = 2222时,输出2301

解题思路:(受insistGoGo 启发,博文地址http://blog.csdn.net/insistgogo/article/details/12240495, 在此表示感谢)

考察 9898996

若找比此数大且最小的不重复数,直接找到此数序列中(从高位开始)首个重复的数字(这里是99),并且将重复数字的低位自增1,如果有进位则进位

这样操作出来会得到一个新数(这里是9899006),得到的新数可能会有新的重复数字出现,对其做同样操作,直到不产生新的重复数字为止

然后将最后一次自增位之后的数字序列变成0101序列,则得到的数字即为要找的数字

文字叙述可能难以理解,下面让我们考察几个数,来理解查找的过程

1. n (输入的数)本身有重复的数

如 9898996

9898996 ---> 9899006 (查找到首个重复数字99,然后对99的低位9自增1) --> 9900006 (因为产生新的重复数字,所以做同上操作) --> 10000006

--> 10100006 (首个重复数字00,自增1) --> 10101010 (没有产生新的重复数字,将01之后的数字序列变成0101序列)

则10101010 就是 大于 9898996 且是最小的不重复数

如 85499

85499 --> 85500 --> 85600 --> 85601

如 8325996

8325996 --》 8326006 --》 8326010

以上都是对99重复的例子,很容易发现,如果数字序列中出现99,则对99做自增后,会影响到99之前的两位

其他重复例子:如56332

56332 --》 56340

如 56443  --》 56450

很容易发现 00 - 88 的重复属于同一类型的, 只需对重复数字的低位自增,然后将后续序列换成0101序列

2. n (输入的数)本身无重复的数

本身无重复的数,是不是直接自增1就可了(既最后一位自增1)? 情况并没有这么简单

如 36954  自增1 变成 36955 (自增1,产生新的重复数字)

如 36549 自增1 变成 36550 (自增1,产生新的重复数字)

如 36539 自增1 变成 36540 (这个尾数也是9呢,但自增1之后,就是要找的数啦)

还有如呢,我还没菊丸栗子呢

如 36956 这种最喜欢啦 因为自增1 查找就结束了   36957 就是要找的

好了,栗子举玩了(谁给我买我最喜欢的板栗啊,都被我举完了哇 呜呜呜~~~)。

透过栗子,我想应该也能发现些什么了吧(发现啥? 规律规律规律啊)

总结一下:
1. n 本身包含重复,重复的类型有两种:
 1-1  : 99  :自增1 之后,会影响到前两位数字,所以在自增之后,指针(用两指针指向当前的两位被考察数字,如99)需向前移动两位,确认是否产生新的重复数字

1-2   : 00 - 88:喜欢这个重复,因为自增1之后,不会影响到前位数字(既指针不需前移),替换后续序列为0101,就可以退出了

2. n本身不包含重复,类型有三种:

2-1  :  (x+1)x9,末尾为9,自增1之后,会影响到前一位数字,指针需向前移动1位(两个指针都前移),查看是否产生新的重复数字,若产生,则变为 1中重复情况

2-2   :   (x+1)x,尾数为x,而前一位比其大1,自增1,会产生新的重复数字,指针不需向前移动,变为1中重复情况

2-3   :   x9 和 yx,x9中的x的前一位数不比x大1,yx不满足2-1 和 2-2中要求,且x不为9, 可直接自增1,然后找到所要找的数,退出。

好了,理解以上的内容,就可以编码实现。

此算法复杂度为O(m),m为n的位数。

用两个指针fpStrNum 和 spStrNum分别指向数的最高位和次高位。

#include <iostream>
#include <cstdlib>
#define MAX 100using namespace std;char* getStrNum(int nNum)
{char *pStrNum = new char[MAX];memset(pStrNum, 0, sizeof(char)*MAX);int i=0;while(nNum){pStrNum[i++] = nNum % 10 + '0';nNum = nNum / 10;}return pStrNum;
}void increase(char *p)
{if(0==*p) *p = 1+'0';else {if(*p<'9') *p += 1;else {*p = '0';increase(p+1);}}
}void set01(char *start, char* end)
{int flag = 0;while(start >= end){if(flag == 0){*start = '0';flag = 1;}else {*start = '0' + 1;flag = 0;}start--;}
}char* MinLargeNumber(int nNum)
{char* pStrNum = getStrNum(nNum);int length = strlen(pStrNum);if(1 == length){increase(pStrNum);return pStrNum;}char* fpStrNum = pStrNum + length -1;char* spStrNum = pStrNum + length -2;while(fpStrNum > pStrNum){if(spStrNum > pStrNum && *fpStrNum != *spStrNum){fpStrNum--;spStrNum--;continue;}// 含重复 if(*fpStrNum == *spStrNum){// 00 - 88 if(*spStrNum < '9') {increase(spStrNum);set01(spStrNum-1, pStrNum);break;}// 99else {increase(spStrNum);fpStrNum += 2;spStrNum += 2;continue;}}// 不含重复 else {// (x+1)x9if(*spStrNum == '9' && (*(fpStrNum+1) - *fpStrNum) == 1){increase(spStrNum);fpStrNum += 1;spStrNum += 1;continue;}// (x+1)x else if((*fpStrNum - *spStrNum) == 1){increase(spStrNum);continue;}// x9 or yxelse {increase(spStrNum);set01(spStrNum-1, pStrNum);break;}}}return pStrNum;
} int main(int argc, char *argv)
{int n;while(scanf("%d", &n) != EOF){char *pStrNum = MinLargeNumber(n);int len = strlen(pStrNum);char *end = pStrNum+len-1;while(end>=pStrNum) printf("%c", *end--);printf("\n");}system("pause");return 0;
}

好啦,收工回家晾衣服

百度14年笔试 - 找出大于某值的最小的不重复数相关推荐

  1. Java黑皮书课后题第10章:*10.17(平方数)找出大于Long.MAX_VALUE的前10个平方数。平方数是指形式为n^2的数

    例如,4.9以及16都是平方数,找到一种有效方法,使程序能快速运行 题目 破题 特别提醒 代码 题目 *10.17(平方数)找出大于Long.MAX_VALUE的前10个平方数.平方数是指形式为n^2 ...

  2. 6-10 找出大于num的最小素数 (10 分)

    本题要求实现一个函数:找出大于num的最小素数,并将其作为函数值返回. 函数接口定义: int Prime_number ( int N ); 其中 N 是用户传入的参数. N 的值不超过int的范围 ...

  3. 6-2 找出大于num的最小素数 (16 分)

    本题要求实现一个函数:找出大于m的最小素数,并将其作为函数值返回. 函数接口定义: int Prime_number ( int N ); 其中 N 是用户传入的参数. N 的值不超过int的范围,函 ...

  4. java_找出大于200的最小质数

    package 课堂练习的项目;public class 找出大于200的最小质数 {public static void main(String[] args) {// TODO 自动生成的方法存根 ...

  5. 【c语言】找出大于m的最小素数,并将其作为函数值返回

    /*找出大于m的最小素数,并将其作为函数值返回*/ #include <math.h> #include <stdio.h> int fun(int m) {int i, k; ...

  6. 程序员花了14个小时找出了长春长生们究竟卖到了哪里去

    程序员花了14个小时找出了长春长生们究竟卖到了哪里去  01前言 全文的观点从技术讨论出发,尽量客观中立,观点及行为为员工自发,不代表本人所在公司及团队. 需要说明的是这次数据是涵盖所有的疫苗数据,并 ...

  7. 输入一个字符串,用子函数完成在字符串中找出ACSII码值最大的字符,将其放在第一个位置,并将该字符前的所有字符向后顺序移动

    <程序设计基础实训指导教程-c语言> ISBN 978-7-03-032846-5 p143 7.1.2 上级实训内容 [实训内容9]输入一个字符串,用子函数完成在字符串中找出ACSII码 ...

  8. 找出列表中最大或最小的元素-python3

    """ 找出列表中最大或最小的元素Version: 1.0.0 Author: Catherine Data: 2019-03-11 """ ...

  9. Linux运维之批量下载指定网站的100个图片文件,并找出大于200KB的文件

    题目为: 有一百个图片文件,它们的地址都是 http://down.fengge.com/img/1.png http://down.fengge.com/img/2.png - 一直到http:// ...

最新文章

  1. 新概念英语(1-137)A pleasant dream
  2. paho mqtt 订阅主题的处理注意事项
  3. 巧用Angular项目的get设置Angular class属性访问的别名
  4. 得到按钮句柄后如何点集_RepPoint:可形变卷积生成的目标轮廓点集
  5. mapper里面select id 后面一直红名_YTG晨晨改ID“进厂找班上了”,如此自嘲,心态还挺好...
  6. matlab局部放大的图中图画法
  7. 几个改变世界的java工具
  8. 如何用JavaScript实现轮播图(幻灯片)的制作
  9. 【软件推荐】还用着Windows自带的看图软件吗?
  10. mysql修改唯一索引
  11. 平板电脑开机出现android,平板电脑常见故障解决方法
  12. EfficientNet理论讲解
  13. uni-app 学习笔记(三)uni-app中的各种引用
  14. 2017年微商行业八大趋势
  15. 酷客多小程序百城宣讲会-郑州站圆满成功
  16. input获取焦点vue_在Vue中输入框自动获取焦点的三种方式
  17. excel文件被写保护怎么解除_如何去掉Excel表格中的密码保护?
  18. mmdeploy快速上手
  19. 电芯容量在前期循环中容量增加_新发现!18650电池钢芯提升电池低温循环性能...
  20. eps罗马柱头制作方法_元阳好的eps罗马柱批发价格,罗马柱子制作

热门文章

  1. 给2020年计算机考研学弟学妹的意见
  2. android的kotlin通讯录,Android Loader的使用以及手机通讯录的获取方法
  3. 主流深度相机选型(双目相机)
  4. 零编程基础获取最新、最权威的县以上行政区划代码信息
  5. 达索系统祝贺阳光动力飞机完成环球飞行
  6. 新媒体运营教程:打造爆款活动方法及策略
  7. 大学四年的各种学习资源整理
  8. 码教授《朗读行者》线下沙龙
  9. 教你如何在虚拟机上安装Linux
  10. 日语能力考试报名技巧