每日一题(97) - 找出大于某值的最小的不重复数
来源:互联网 发布:微信聊天数据怎么恢复 编辑:程序博客网 时间:2024/06/05 17:48
题目来自百度14年校招天津站笔试题,当时思路混乱导致被虐。
题目:n为正整数,求比这个数大且最小的不重复数,重复数为相邻两位数字相同,如1101为重复数,1231为不重复数。
举例:当n = 2222时,输出2301
方法:
1、暴力解决,最直观的方法
对于每一个大于n个数,都做一次判断,找出第一个满足条件的数。
2、O(m)算法,m为已知正整数的位数。
思路:
(1)先把数字变成字符串,此时字符串低位存储数字的低位。
(2)由高位到低位依次处理(字符串的高位代表着数字的高位),一旦高位某个位置pos正常改变,则从[0,pos - 1]之间的数据可以直接用0和1填充。这里的正常是指,pos位置改变后,对[pos+1,..]之间的数字没有影响,此时的特殊情况为包含"99"的情况。
(3)为了让数最小,可以现在pos - 1填充0,之后交错填充1,这里前提是pos的位置上是一个非0的数,如果是0,则pos - 1填充1,之后交错填充0。
(4)把字符串表示的数字变成数字。
时间复杂度:
假设数字长度为m,则数字变字符,遍历数字一遍,之后执行算法是最多遍历数字次数为3便,最后字符变数字遍历一遍,所以时间复杂度为O(m)。
举例:
待处理的数据: 98999
(1) 数字98999变成字符串"99989"
(2)这里假设nCurBit初始化指向8(99989),nLastBit初始化指向9(99989)。
<1> 由于有nCurBit不等于nLastBit,则nCurBit指向前一位,即为9,(99989),而nLastBit指向8(99989)。
<2> 此时仍然有nCurBit不等于nLastBit,仍然有nCurBit--,即nCurBit指向9(99989),nLastBit也指向9(99989)
<3> 此时nCurBit等于nLastBit,这是由于我们要求比98999大的数,即nCurBit要++。
<4> 这里比较特殊的一点是,nCurBit已经为9了(99989),再加会向前进位(会影响之前已经处理的位),此时加1后变成90099,其中此次变化影响了三个数,此时待处理的位置应该回退到被影响的位的第一位中(90099),这是因为进位后的某些位可能和原来的某些数字是重复的。
<5> 此时nCurBit指向第一个被影响的位置(指向9,即90099),nLastBit也指向9(90099),而继续往左处理
<6> 之后,还是采用之前的策略处理,直到某个数加1后,不会对那些已经处理好的数字产生影响,就停止。之后剩余的数字直接填充0或1即可。
貌似说的混乱,凑合瞅瞅。。
代码:
(1)暴力解决
#include <iostream>#include <assert.h>using namespace std;bool IsNoRepetition(int nNum){int nCurBit = 0;int nLastBit = -1;while (nNum){if (-1 == nLastBit){nLastBit = nNum % 10;}else{nCurBit = nNum % 10;if (nCurBit == nLastBit){return false;}nLastBit = nCurBit;}nNum /= 10;}return true;}int MaxNum_Force(int nNum){assert(nNum > 9);while (!IsNoRepetition(nNum)){nNum++;}return nNum;}int main(){int nNum = 0;cin>>nNum;cout<<MaxNum_Force(nNum)<<endl;system("pause");return 1;}
(2)O(n)算法
#include <iostream>#include <assert.h>using namespace std;char* IntToString(int nNum){assert(nNum > 9);int nCur = 0;char* pStrNum = new char[20];memset(pStrNum,0,sizeof(char) * 20);while(nNum){pStrNum[nCur++] = nNum % 10 + '0';nNum /= 10;}return pStrNum;}int StringToInt(char* pStrNum){assert(pStrNum != NULL);int nNewNum = 0;int nLen = strlen(pStrNum);while (nLen >= 1){nNewNum *= 10;nNewNum += (pStrNum[nLen - 1] - '0');nLen--;}return nNewNum;}int MaxNum(int nNum){assert(nNum > 9);char* pStrNum = IntToString(nNum);int nCur = strlen(pStrNum);char cLastBit = pStrNum[--nCur];nCur--;while(nCur >= 0){if (pStrNum[nCur] != cLastBit){cLastBit = pStrNum[nCur--];}else if(pStrNum[nCur] != '9') //nCur位不等于9,则直接加1{pStrNum[nCur]++;break;}else //nCur位等于9,则会影响前面已经处理的数,需要回退{ while(pStrNum[nCur] == '9'){pStrNum[nCur++] = '0';}//进位if (pStrNum[nCur] == 0){pStrNum[nCur] = '1';}else{pStrNum[nCur]++;}cLastBit = pStrNum[nCur + 1];if (cLastBit != pStrNum[nCur]){break;}}}nCur--;//剩余的位直接填充0或者1while (nCur >= 0){if (pStrNum[nCur + 1] == '0'){pStrNum[nCur] = '1';}else{pStrNum[nCur] = '0';}nCur--;}int nNewNum = StringToInt(pStrNum);delete[] pStrNum;return nNewNum;}int main(){int nNum = 0;cin>>nNum;cout<<MaxNum(nNum)<<endl;system("pause");return 1;}
- 每日一题(97) - 找出大于某值的最小的不重复数
- 百度14年笔试 - 找出大于某值的最小的不重复数
- 查找大于一正整数的最小的不重复数
- 查找最大的不重复数,查找大于给定数字的最小不重复数
- 实现返回大于A的最小“不重复数” 百度2014校招笔试题
- 百度笔试:求大于n的最小的不重复数,不重复数是指相邻两个数不相同
- 找出大于一个数的最小回文数
- 每日一题(28) - 找出绝对值最小的元素
- 有道难题2009复赛题解答(Java版):求大于给定数的最小不重复数
- 有道难题2009复赛题解答(Java版):求大于给定数的最小不重复数
- 有道难题2009复赛题解答(Java版):求大于给定数的最小不重复数
- 每日一题(59) - 把数组排成最小的数
- 每日一题--把数组排成最小的数
- 找出大于给定数数最小的素数
- java_找出大于200的最小质数
- 给出任意一个正整数,算出大于它的最小不重复数——最高效[2014百度笔试题]
- 百度笔试题:找最小的不重复数
- 每日一题(23) - 找出数组中重复的数据和丢失的数据。
- 早该知道的7个JavaScript技巧
- 黑马程序员-JAVA学习之环境搭配
- 人名翻译规则
- hdu4766 network 圆与圆交 (2013网络赛)
- Java多线程之syncronized(二)
- 每日一题(97) - 找出大于某值的最小的不重复数
- POJ 2299 Ultra-QuickSort(归并排序求逆序数)
- C++多重继承,虚函数表的次序
- Distributed garbage collection used in RMI
- POJ 1659 Frogs' Neighborhood
- 查找算法_二分查找
- 尾部插入节点
- Yii中CDbCriteria常用总结(转)
- Android网络编程——https 不验证证书方式(信任所有证书)