2016-08-23 11:32:06 +08:00
|
|
|
// Source : https://leetcode.com/problems/lexicographical-numbers/
|
|
|
|
// Author : Hao Chen
|
|
|
|
// Date : 2016-08-23
|
|
|
|
|
|
|
|
/***************************************************************************************
|
|
|
|
*
|
|
|
|
* Given an integer n, return 1 - n in lexicographical order.
|
|
|
|
*
|
|
|
|
* For example, given 13, return: [1,10,11,12,13,2,3,4,5,6,7,8,9].
|
|
|
|
*
|
|
|
|
* Please optimize your algorithm to use less time and space. The input size may be as
|
|
|
|
* large as 5,000,000.
|
|
|
|
***************************************************************************************/
|
|
|
|
class Solution {
|
|
|
|
|
|
|
|
//Solution 1: convert the int to string for sort, Time complexity is high (Time Limited Error)
|
|
|
|
public:
|
|
|
|
vector<int> lexicalOrder01(int n) {
|
|
|
|
vector<int> result;
|
|
|
|
for (int i=1; i<=n; i++) {
|
|
|
|
result.push_back(i);
|
|
|
|
}
|
|
|
|
sort(result.begin(), result.end(), this->myComp);
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
private:
|
|
|
|
static bool myComp(int i,int j) {
|
|
|
|
static char si[32]={0}, sj[32]={0};
|
|
|
|
sprintf(si, "%d\0", i);
|
|
|
|
sprintf(sj, "%d\0", j);
|
|
|
|
return (strcmp(si, sj)<0);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//Solution 2 : using recursive way to solution the problem, 540ms
|
|
|
|
public:
|
|
|
|
vector<int> lexicalOrder02(int n) {
|
|
|
|
vector<int> result;
|
|
|
|
for (int i=1; i<=n && i<=9; i++) {
|
|
|
|
result.push_back(i);
|
|
|
|
lexicalOrder_helper(i, n, result);
|
|
|
|
}
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
|
|
|
void lexicalOrder_helper(int num, int& n, vector<int>& result) {
|
|
|
|
for (int i=0; i<=9; i++) {
|
|
|
|
int tmp = num * 10 + i;
|
|
|
|
if (tmp > n) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
result.push_back(tmp);
|
|
|
|
lexicalOrder_helper(tmp, n, result);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//Solution 3: no recursive way, but the code is not easy to read
|
|
|
|
public :
|
|
|
|
vector<int> lexicalOrder03(int n) {
|
|
|
|
vector<int> result;
|
|
|
|
int curr = 1;
|
|
|
|
while (result.size()<n) {
|
|
|
|
// Step One
|
|
|
|
// ---------
|
|
|
|
//Adding all of the possible number which multiply 10 as much as possible
|
|
|
|
// such as: curr = 1, then 1, 10, 100, 1000 ...
|
|
|
|
// curr = 12, then 12, 120, 1200, ...
|
|
|
|
for (; curr <= n; curr*=10 ) {
|
|
|
|
result.push_back(curr);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Step Two
|
|
|
|
// ---------
|
|
|
|
// After find the number which multiply 10 greater than `n`, then go back the previous one,
|
|
|
|
// and keep adding 1 until it carry on to next number
|
|
|
|
// for example:
|
|
|
|
// curr = 100, then we need evalute: 11,12,13,14,15,16,17,18,19, but stop at 20
|
|
|
|
// curr = 230, then we need evaluate: 24,25,26,27,28,29, but stop at 30.
|
|
|
|
curr = curr/10 + 1;
|
|
|
|
for (; curr <= n && curr % 10 != 0; curr++) {
|
|
|
|
result.push_back(curr);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Step Three
|
|
|
|
// ----------
|
|
|
|
// Now, we finished all of the number, we need go back for next number
|
|
|
|
// Here is a bit tricky.
|
|
|
|
//
|
|
|
|
// Assuming the n is 234, and Step One evaluted 190, and Step Two, evaluted 191,192,...,199
|
|
|
|
// Now, the `curr` is 200, and we need start from 2 instead of 20, that's why need keep dividing 10
|
|
|
|
for (; curr%10 == 0; curr/=10);
|
|
|
|
|
|
|
|
}
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//start point
|
|
|
|
public:
|
|
|
|
vector<int> lexicalOrder(int n) {
|
2016-08-24 11:06:07 +08:00
|
|
|
srand(time(NULL));
|
|
|
|
if (rand()%2)
|
|
|
|
return lexicalOrder02(n); // recursive way 560ms
|
|
|
|
else
|
2016-08-23 11:32:06 +08:00
|
|
|
return lexicalOrder03(n); // non-recursive way, 460ms
|
|
|
|
}
|
|
|
|
|
|
|
|
};
|