题目描述
给你一个由小写字母组成的字符串 s ,以及一个整数 k 。
首先,用字母在字母表中的位置替换该字母,将 s 转化 为一个整数(也就是,‘a’ 用 1 替换,‘b’ 用 2 替换,… ‘z’ 用 26 替换)。接着,将整数 转换 为其 各位数字之和 。共重复 转换 操作 k 次 。
例如,如果 s = “zbax” 且 k = 2 ,那么执行下述步骤后得到的结果是整数 8 :
转化:“zbax” ➝ “(26)(2)(1)(24)” ➝ “262124” ➝ 262124
转换 #1:262124 ➝ 2 + 6 + 2 + 1 + 2 + 4 ➝ 17
转换 #2:17 ➝ 1 + 7 ➝ 8
返回执行上述操作后得到的结果整数。示例 1:
输入:s = “iiii”, k = 1
输出:36
解释:操作如下:
转化:“iiii” ➝ “(9)(9)(9)(9)” ➝ “9999” ➝ 9999
转换 #1:9999 ➝ 9 + 9 + 9 + 9 ➝ 36
因此,结果整数为 36 。示例 2:
输入:s = “leetcode”, k = 2
输出:6
解释:操作如下:
转化:“leetcode” ➝ “(12)(5)(5)(20)(3)(15)(4)(5)” ➝ “12552031545” ➝ 12552031545
转换 #1:12552031545 ➝ 1 + 2 + 5 + 5 + 2 + 0 + 3 + 1 + 5 + 4 + 5 ➝ 33
转换 #2:33 ➝ 3 + 3 ➝ 6
因此,结果整数为 6 。提示:
1 <= s.length <= 100
1 <= k <= 10
s 由小写英文字母组成
方法一:模拟,取余整除法
思路:
- 首先我设置了一个数组 nums,里面放置字符串 s 的数字转换,依次遍历字符串 s,将其转换为对应的数字;
- 由于 k 至少为 1 ,因为可以对遍历数组,让数组中所有数字的个位和十位相加(使用整除和取余),此时已经完成了一次 k 操作, 因此 k --;
- 接下来判断是否已经完成了操作,如果没有,则继续按照上述方法遍历,注意,当结果为个位数的话,就可以退出循环,因为个位数无论如何相加都等于它本身。
情况
- 通过;
收获
- 这一个题蛮简单的,由于我对很多 api 不太熟悉,用了最原始的方法(取余 + 整除)来计算各个位置的数字和,幸好取余的效率很高;
- 我直接将字符串 -> 存放数字的数组 -> 操作一次变成整数 ,省略了将字符串 -> 数字字符串 -> 整数 ->操作一次 的步骤,虽然代码看起来冗长些,但速度应该快了点。
时间复杂度:O(n),由于 n <= 100 ,在最坏情况下, s 由 100 个 s 字母组成, 对应数字 19 ,则:
- 第一次操作后,数字为 (1 + 9) * 100 = 1000,说明第一次操作后的数字范围在 [0, 1000] 之间,其中最大的数字和为 999;
- 也就是说第二次操作的最大数字为 9 + 9 + 9 = 27 ,第二次操作后的数字范围为 [0, 27],其中最大的数字和为 19 ;
- 说明第三次操作的最大数字为 1 + 9 = 10 ,第三次操作后的数字范围为 [0, 10] ,其中最大的数字和为 9,说明第四次操作后,一定会得到个位数的结果;
- 因此,循环最多执行 4 次,除了第一次循环处理的长度为字符串长度 n ,其余都小于 n,因此这一部分的时间复杂度看作 O(n),总的时间复杂度为 O(n);
空间复杂度:O(n),n 为字符串 s 的长度;
class Solution {
public:
int getLucky(string s, int k) {
int n = s.size();
int sum = 0;
vector<int> nums(n);
for(int i=0; i<n; i++) nums[i] = s[i] - 'a' + 1;
for(auto& num : nums){
while(num){
sum += num % 10;
num /= 10;
}
}
k --;
int res = sum;
while(k){
res = 0;
while(sum){
res += sum % 10;
sum /= 10;
}
if(res < 10) break;
sum = res;
k --;
}
return res;
}
};
方法二:模拟,使用字符串转换函数
思路:
- 首先将字母字符串转换为数字字符串;
- 开始遍历数字字符串,每个数字进行累加,当 满足操作次数 或 结果为个位数 ,结束循环。
情况
- 通过;
收获
- 方法二的思路更贴近于题目;
- 灵活运行字符串函数:
- to_string :数字 -> 字符串;
- stoi : 字符串 -> 数字;
时间复杂度:O(n),和方法一相同,不赘述;
空间复杂度:O(n), n 为字符串长度。
class Solution {
public:
int getLucky(string s, int k) {
string digits;
for(auto& c : s) digits += to_string(c - 'a' + 1);
for(int i=1; i<=k && digits.size()>1;i++){
int sum = 0;
for(auto& ch : digits) sum += ch - '0';
digits = to_string(sum);
}
return stoi(digits);
}
};