class Solution {
public:
int digitAtIndex(int n) {
long long i = 1, s = 9, base = 1;//i表示是几位数,s表示位数共有多少个,base表示位数的起始值。
while(n > i * s) {
// 9, 90, 900, 9000, 90000, i * s表示位数总共占多少位。
n -= i * s; // 1000 - 9 - 90 * 2 - 900 * 3 ,当i= 3 时不符合条件,说明是在三位数里面。
i ++;
s *= 10;
base *= 10;
}
//求第i位数的第几个数, 1000 - 9 - 180 = n , n / 3 + base - 1(考虑0故减1),
//c++中只有下取整,所以当需要上取整时要处理一下,也就是说 n/i向上取整等价于 (n + i - 1)/i。
int number = base + (n + i - 1) / i - 1;
int r = n % i ? n % i : i; // 除不尽就是第几位,除尽力了就是最后一位。
for (int j = 0; j < i - r; j ++) number /= 10; //求数的第i - r位,取出第i - r位。
return number % 10;
}
};
把数组排成最小的数
也是一道非常经典的题目。
- 首先我们需要知道什么样的数应该放在前面,所以我们需要定义两个数的排序。这个排序规则并不只是单纯的比较数值的大小,例如:321,32尽管32小于321的但是32132是小于32321的,所以我们需要自己定义一种排序规则,用来替换原来的符号比较。比较的思路为:如果ab<ba那么就说a比b“小”,a应该放在b的前面。
- 然后有了比较规则之后我们就可以进行判断,将数组中“小”的元素放在数组的前面,最后将数组每个元素按照顺序拼接输出就可以了。
class Solution {
public:
static bool mycmp(int a, int b) {
auto as = to_string(a), bs = to_string(b);
return as + bs < bs + as;
}
string printMinNumber(vector<int>& nums) {
string res;
sort(nums.begin(), nums.end(), mycmp);
for (auto x : nums) res += to_string(x);
return res;
}
};
把数字翻译成字符串
绝大部分的计数问题都可以看成是dp问题。
类比爬楼梯,dp[n] = dp[n-1]+dp[n-2],dp[n]代表走到最后一个字符,能有多少多少中翻译方法。对于访问到当前的字符dp[n],能有多少中翻译?
- 当前字符翻译为1个字符这是一种方法,dp[n] = dp[n-1]
- 当前字符呵前一个字符共同翻译为一种方法 dp[n]+=dp[n-2],此时的条件为前后两个字符可以翻译为同一个字符。还有 04,05,06,这种只能翻译为1中,其组合不能作为一种翻译,所以要在[10,25]
class Solution {
public:
int getTranslationCount(string s) {
int n = s.size();
vector<int> f(n + 1);
f[0] = 1;
for (int i = 1; i <= n; i++) {
f[i] += f[i- 1];
int t = (i >= 2)