问题分析
小U正在从数字 0 开始数偶数,并将这些偶数依次连接形成一个无穷长的字符串。给定一个数字 n,我们的任务是找出该字符串中的第 n 个字符。
例如:
- 偶数序列是:
0, 2, 4, 6, 8, 10, 12, 14, 16, ... - 连接后的字符串是:
0246810121416... - 如果
n = 6,那么第 6 个字符是1。
思路解析
由于字符串是由一系列偶数组成的,我们可以将这些偶数依次连接,并查找字符串中的第 n 个字符。
-
偶数生成:偶数从 0 开始,逐渐递增,每个偶数占据一定的字符长度。例如,
0是 1 个字符,2是 1 个字符,10是 2 个字符,100是 3 个字符。 -
字符串构建:我们可以按顺序生成偶数,将它们追加到一个字符串中。直到字符串的长度大于等于
n。 -
获取结果:一旦字符串长度超过或等于
n,我们可以直接返回字符串中第n个字符。
解法实现
我们将用一个循环来生成偶数,逐步将其转换为字符串并连接。通过 StringBuilder 可以高效地拼接字符串。每次将当前偶数转换为字符串后,检查拼接后的字符串长度是否已经达到 n,如果达到了,直接返回第 n 个字符。
代码详解
public class Main {
public static int solution(int n) {
// 使用 StringBuilder 来存储拼接的偶数字符串
StringBuilder currentString = new StringBuilder();
int currentEven = 0;
// 循环生成偶数并追加到字符串中
while (true) {
// 将当前偶数转换为字符串并追加到总字符串中
currentString.append(currentEven);
// 检查当前字符串的长度是否达到或超过 n
if (currentString.length() >= n) {
// 返回第 n 个字符。注意:charAt 返回的是字符,需要转换为数字
return currentString.charAt(n - 1) - '0'; // '0' 的 ASCII 值是 48,因此需要减去 48
}
// 生成下一个偶数
currentEven += 2;
}
}
public static void main(String[] args) {
// 测试样例
System.out.println(solution(6)); // 输出 1
System.out.println(solution(10)); // 输出 1
System.out.println(solution(15)); // 输出 8
}
}
代码详解
-
初始化:
StringBuilder currentString用来存储拼接的偶数字符串。int currentEven = 0初始化当前偶数为 0。
-
拼接字符串:
- 在每次循环中,将当前偶数
currentEven转换为字符串并追加到currentString中。 - 如果
currentString.length()已经大于等于n,则说明目标字符已经出现在字符串中,使用currentString.charAt(n - 1)获取第n个字符(注意n是 1 基准,所以需要减去 1)。
- 在每次循环中,将当前偶数
-
返回结果:
currentString.charAt(n - 1)返回字符类型的数据,所以需要减去字符'0'的 ASCII 值来获得对应的数字。
-
测试:
- 在
main方法中,我们使用了三个测试样例来验证代码是否正确。
- 在
复杂度分析
-
时间复杂度:生成偶数并拼接到字符串的时间复杂度是 O(k),其中
k是生成偶数的数量,直到字符串长度达到n。在最坏情况下,我们可能需要生成约n个字符,因此时间复杂度为 O(n)。 -
空间复杂度:存储拼接的字符串的空间复杂度是 O(n),因为我们至少需要存储
n个字符。
样例分析
样例 1:
输入:n = 6
偶数字符串:0246810121416...
第 6 个字符是 1,输出:1
样例 2:
输入:n = 10
偶数字符串:02468101214...
第 10 个字符是 1,输出:1
样例 3:
输入:n = 15
偶数字符串:0246810121416...
第 15 个字符是 8,输出:8
总结
该问题可以通过生成偶数并逐步拼接字符串来解决,直到找到目标位置的字符。使用 StringBuilder 可以有效地拼接字符串,避免了频繁的字符串拼接带来的性能问题。通过模拟生成过程,我们能够准确地找出字符串中指定位置的字符。