“方法能助你登上高峰,但如果找不到方法,你只能在下面徘徊。”——费希特
题目
Alice 和 Bob 正在玩一个游戏。最初,Alice 有一个字符串 word = "a"
。
给定一个正整数 k
。
现在 Bob 会要求 Alice 执行以下操作 无限次 :
- 将
word
中的每个字符 更改 为英文字母表中的 下一个 字符来生成一个新字符串,并将其 追加 到原始的word
。
例如,对 "c"
进行操作生成 "cd"
,对 "zb"
进行操作生成 "zbac"
。
在执行足够多的操作后, word
中 至少 存在 k
个字符,此时返回 word
中第 k
个字符的值。
注意,在操作中字符 'z'
可以变成 'a'
。
难度:简单
分析
模拟没什么值得说的地方,但是位运算的思路很巧妙,笔者必须记录一下。
我们观察题目的操作,可以知道每次拼接上的字符串长度为1,2,4,……,所以整体的序列为1,1,2,4,……,并且由于每个新字符串的长度与之前的字符串相同,每个新字符串内部的序列也为1,1,2,4,……。因此,可以知道每跳过2的幂次个数,会到达一个序列的开始(1+1=2,1+1+2=4,1+1+2+4=8……)。现在我们考虑第K个字符,需要从'a'跳过K-1个数,根据K-1的二进制表示,从最高位开始看第1个1,它代表需要跳过2的幂次个数,因此到达一个序列的开始,并且根据题意,首个字符为'b',再看第2个1,它代表需要在该序列中跳过2的幂次个数,同样到达一个序列的开始,因为目前序列的首个字符为'b',因此该序列的首个字符为'c'。综上所述,二进制位中每有1个1,得到的字符就会增加1位。
解答
模拟
class Solution {
public char kthCharacter(int k) {
StringBuilder sb=new StringBuilder();
sb.append('a');
while (sb.length()<k){
int count=sb.length();
for (int i=0;i<count;i++){
char v=sb.charAt(i);
char next=(char)(v+1);
if (v=='z'){
next='a';
}
sb.append(next);
}
}
return sb.charAt(k-1);
}
}
位运算
class Solution {
public char kthCharacter(int k) {
return (char)('a'+Integer.bitCount(k-1)%26);
}
}