百度14年笔试 - 找出大于某值的最小的不重复数
百度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年笔试 - 找出大于某值的最小的不重复数相关推荐
- Java黑皮书课后题第10章:*10.17(平方数)找出大于Long.MAX_VALUE的前10个平方数。平方数是指形式为n^2的数
例如,4.9以及16都是平方数,找到一种有效方法,使程序能快速运行 题目 破题 特别提醒 代码 题目 *10.17(平方数)找出大于Long.MAX_VALUE的前10个平方数.平方数是指形式为n^2 ...
- 6-10 找出大于num的最小素数 (10 分)
本题要求实现一个函数:找出大于num的最小素数,并将其作为函数值返回. 函数接口定义: int Prime_number ( int N ); 其中 N 是用户传入的参数. N 的值不超过int的范围 ...
- 6-2 找出大于num的最小素数 (16 分)
本题要求实现一个函数:找出大于m的最小素数,并将其作为函数值返回. 函数接口定义: int Prime_number ( int N ); 其中 N 是用户传入的参数. N 的值不超过int的范围,函 ...
- java_找出大于200的最小质数
package 课堂练习的项目;public class 找出大于200的最小质数 {public static void main(String[] args) {// TODO 自动生成的方法存根 ...
- 【c语言】找出大于m的最小素数,并将其作为函数值返回
/*找出大于m的最小素数,并将其作为函数值返回*/ #include <math.h> #include <stdio.h> int fun(int m) {int i, k; ...
- 程序员花了14个小时找出了长春长生们究竟卖到了哪里去
程序员花了14个小时找出了长春长生们究竟卖到了哪里去 01前言 全文的观点从技术讨论出发,尽量客观中立,观点及行为为员工自发,不代表本人所在公司及团队. 需要说明的是这次数据是涵盖所有的疫苗数据,并 ...
- 输入一个字符串,用子函数完成在字符串中找出ACSII码值最大的字符,将其放在第一个位置,并将该字符前的所有字符向后顺序移动
<程序设计基础实训指导教程-c语言> ISBN 978-7-03-032846-5 p143 7.1.2 上级实训内容 [实训内容9]输入一个字符串,用子函数完成在字符串中找出ACSII码 ...
- 找出列表中最大或最小的元素-python3
""" 找出列表中最大或最小的元素Version: 1.0.0 Author: Catherine Data: 2019-03-11 """ ...
- Linux运维之批量下载指定网站的100个图片文件,并找出大于200KB的文件
题目为: 有一百个图片文件,它们的地址都是 http://down.fengge.com/img/1.png http://down.fengge.com/img/2.png - 一直到http:// ...
最新文章
- 新概念英语(1-137)A pleasant dream
- paho mqtt 订阅主题的处理注意事项
- 巧用Angular项目的get设置Angular class属性访问的别名
- 得到按钮句柄后如何点集_RepPoint:可形变卷积生成的目标轮廓点集
- mapper里面select id 后面一直红名_YTG晨晨改ID“进厂找班上了”,如此自嘲,心态还挺好...
- matlab局部放大的图中图画法
- 几个改变世界的java工具
- 如何用JavaScript实现轮播图(幻灯片)的制作
- 【软件推荐】还用着Windows自带的看图软件吗?
- mysql修改唯一索引
- 平板电脑开机出现android,平板电脑常见故障解决方法
- EfficientNet理论讲解
- uni-app 学习笔记(三)uni-app中的各种引用
- 2017年微商行业八大趋势
- 酷客多小程序百城宣讲会-郑州站圆满成功
- input获取焦点vue_在Vue中输入框自动获取焦点的三种方式
- excel文件被写保护怎么解除_如何去掉Excel表格中的密码保护?
- mmdeploy快速上手
- 电芯容量在前期循环中容量增加_新发现!18650电池钢芯提升电池低温循环性能...
- eps罗马柱头制作方法_元阳好的eps罗马柱批发价格,罗马柱子制作