- Lucky Number
People usually think that a number that only contains 3 or 5 is a lucky number.
Now given an integer n, and you need to find the smallest lucky number that is not less than N and the number of occurrences of 3 in this lucky number is the same as the number of occurrences of 5.
Example
Example 1:
Input: n = “3500”
Output: “3535”
Explanation:
The smallest lucky number is 3533, but the number of occurrences of 3 is not equal to the number of occurrences of 5.
The second smallest lucky number is 3535, and the number of occurrences of 3 is equal to the number of occurrences of 5.
Example 2:
Input: n = “1”
Output: “35”
Notice
1 ≤ n ≤ 10^100000
解法1:
这题不容易。
我参考了一些网上的做法,再加上自己的改进。终于过了。
基本思想是基于next_permutation()函数,但是出发的那个基点minStr选择很有技巧,不然遇到规模大的Input肯定超时。
假设输入是
"51443924594061573070619476735114529340233670970104091717691753660643“
我们考虑3种minStr
minStr =“33333333333333333333333333333333355555555555555555555555555555555555”
minStr2 = “53535353535353535353535353535353535353535353535353535353535353535353”
minStr3 = “53333333333333333333333333333333335555555555555555555555555555555555”
即minStr是333…555…
minStr2是535353…53
minStr3是5333…355…5
显然minStr<minStr3<minStr2
其中minStr3的选择很有技巧,注意第一个字符是5,后面跟len/2个3,然后又跟len/2-1个5。
当n[0]=5时,如果n比minStr大,但是比minStr3小,当然就从minStr3开始找。如果n比minStr3大,但是比minStr2小,就从minStr2开始找。
上面我写的可能不对,现在回想一下,实际上n[0]=5时n肯定比minStr大。理论上如果n比minStr2小,minStr3就应该是出发点,不需要再跟minStr2比较。如果n比minStr2还大,则minStr2是出发点。
2) maxStr=555…53…333.
在next_permutation的循环中,如果超过了maxStr就不要找了。如果超过了还没找到,比如说99, minStr=‘35’, maxStr=‘53’,则在minStr前后加上’3’和’5‘即可。
代码如下:
class Solution {
public:
/**
* @param n: the n
* @return: the smallest lucky number that is not less than n
*/
string luckyNumber(string &n) {
string strN, minStr, maxStr, minStr2, minStr3;
string result;
int len = n.size();
int origLen = len;
bool foundIt = false;
if (len & 0x1) len++;
for (int i = 0; i < (len >> 1); ++i) {
minStr = minStr + '3';
maxStr = maxStr + '5';
}
for (int i = (len >> 1); i < len; ++i) {
minStr = minStr + '5';
maxStr = maxStr + '3';
}
if (origLen & 0x1) {
return minStr;
}
if (n[0] == '3') {
minStr2 = string(len, '3'); //or string midStr(len, '3');
for (int i = 0; i < len; ++i) {
if (i & 0x1) minStr2[i] = '5';
}
if (n.compare(minStr) > 0 && n.compare(minStr2) < 0) minStr = minStr2;
}
if (n[0] == '5') {
minStr2 = string(len, '5'); //or string midStr(len, '5');
for (int i = 0; i < len; ++i) {
if (i & 0x1) minStr2[i] = '3';
}
minStr3 = string(len, '3');
minStr3[0] = '5';
for (int i = (len >> 1) + 1; i < len; ++i) minStr3[i] = '5';
if (n.compare(minStr) > 0 && n.compare(minStr3) < 0) minStr = minStr3;
if (n.compare(minStr3) > 0 && n.compare(minStr2) < 0) minStr = minStr2;
}
strN = minStr;
do {
if (strN.compare(maxStr) > 0) {
foundIt = false;
break;
}
if (strN.compare(n) >= 0) {
result = strN;
foundIt = true;
break;
}
} while(next_permutation(strN.begin(), strN.end()));
if (!foundIt) {
result = '3' + strN + '5';
}
return result;
}
};