题目:
A strobogrammatic number is a number that looks the same when rotated 180 degrees (looked at upside down).
Write a function to count the total strobogrammatic numbers that exist in the range of low <= num <= high.
For example,
Given low = "50", high = "100", return 3. Because 69, 88, and 96 are three strobogrammatic numbers.
Note:
Because the range might be a large number, the low and high numbers are represented as string.
在Strobogrammatic Number II的基础上,统计从len(low)到len(high)为n的所有在范围内的个数。Python会超时就不给出了。
首先给出无优化版本,296ms。
class Solution {
public:
int strobogrammaticInRange(string low, string high) {
this->low = low;
this->high = high;
unordered_map<char, string> d;
d.insert(pair<char, string>('0', "0"));
d.insert(pair<char, string>('1', "1"));
d.insert(pair<char, string>('6', "9"));
d.insert(pair<char, string>('8', "8"));
d.insert(pair<char, string>('9', "6"));
string s = "01869";
for(int i = low.length(); i <= high.length(); i++) {
int mid = i / 2;
string result = "";
bool oneMore = (bool)(i % 2);
recursion(d, result, mid, 0, s, oneMore);
}
return this->count;
}
void recursion(unordered_map<char, string> &d, string result, int recur, int iter, string s, bool &oneMore) {
if(iter > recur) {
for(int i = 0; i < 3; i++) {
if(stoll(result.substr(0, recur) + s[i] + result.substr(recur)) <= stoll(this->high) && stoll(result.substr(0, recur) + s[i] + result.substr(recur)) >= stoll(this->low)) {
this->count++;
}
}
return;
}
if(iter == recur) {
if(oneMore) {
recursion(d, result, recur, iter + 1, s, oneMore);
} else {
if(stoll(result) <= stoll(this->high) && stoll(result) >= stoll(this->low)) {
this->count++;
}
}
return;
}
if(iter == 0) {
for(int i = 1; i < 5; i++) {
recursion(d, s[i] + d[s[i]], recur, iter + 1, s, oneMore);
}
} else {
for(int i = 0; i < 5; i++) {
recursion(d, result.substr(0, iter) + s[i] + d[s[i]] + result.substr(iter), recur, iter + 1, s, oneMore);
}
}
}
private:
string low, high;
int count = 0;
};
后来想想,可以把之前的计算结果缓存起来,这样不用每次重新计算。然并卵。还是需要196ms,只提升了100ms。
class Solution {
public:
int strobogrammaticInRange(string low, string high) {
this->low = stoll(low);
this->high = stoll(high);
unordered_map<char, string> d;
d.insert(pair<char, string>('0', "0"));
d.insert(pair<char, string>('1', "1"));
d.insert(pair<char, string>('6', "9"));
d.insert(pair<char, string>('8', "8"));
d.insert(pair<char, string>('9', "6"));
unordered_map<int, vector<string>> save;
string s = "01869";
for(int i = low.length(); i <= high.length(); i++) {
vector<string> results;
int mid = i / 2;
string result = "";
bool oneMore = (bool)(i % 2);
if(oneMore && save.find(i - 1) != save.end()) {
for(auto j : save[i - 1]) {
recursion(d, j, mid, mid, s, oneMore, results);
}
} else if(!oneMore && save.find(i - 2) != save.end()) {
for(auto j : save[i - 2]) {
recursion(d, j, mid, mid - 1, s, oneMore, results);
}
} else {
recursion(d, "", mid, 0, s, oneMore, results);
}
save.insert(pair<int, vector<string>>(i, results));
}
return this->count;
}
void recursion(unordered_map<char, string> &d, string result, int recur, int iter, string s, bool &oneMore, vector<string> &results) {
if(iter > recur) {
for(int i = 0; i < 3; i++) {
string t = result.substr(0, recur) + s[i] + result.substr(recur);
long long r = stoll(t);
if(r <= this->high && r >= this->low) {
this->count++;
results.push_back(t);
}
}
return;
}
if(iter == recur) {
if(oneMore) {
recursion(d, result, recur, iter + 1, s, oneMore, results);
} else {
long long r = stoll(result);
if(r <= this->high && r >= this->low) {
this->count++;
results.push_back(result);
}
}
return;
}
if(iter == 0) {
for(int i = 1; i < 5; i++) {
recursion(d, s[i] + d[s[i]], recur, iter + 1, s, oneMore, results);
}
} else {
for(int i = 0; i < 5; i++) {
recursion(d, result.substr(0, iter) + s[i] + d[s[i]] + result.substr(iter), recur, iter + 1, s, oneMore, results);
}
}
}
private:
long long low, high;
int count = 0;
};