中心对称数 II
难度:
标签:
题目描述
代码结果
运行时间: 43 ms, 内存: 26.5 MB
/*
* 题目思路:
* 中心对称数是指一个数字旋转180度之后看起来还是一样的数字。
* 比如数字 '69' 旋转180度之后是 '96',数字 '88' 旋转180度之后是 '88'。
* 要求找出所有长度为 n 的中心对称数。
*
* 解题步骤:
* 1. 递归生成长度为 n 的所有中心对称数。
* 2. 定义两个字符数组,分别用于存储可以构成中心对称数的字符对。
* 3. 使用递归函数生成中心对称数。
* 4. 处理基准情况和递归情况,保证生成的数是有效的中心对称数。
*/
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class StrobogrammaticNumberIIStream {
public List<String> findStrobogrammatic(int n) {
return helper(n, n).collect(Collectors.toList());
}
private Stream<String> helper(int n, int m) {
if (n == 0) return Stream.of("");
if (n == 1) return Stream.of("0", "1", "8");
return helper(n - 2, m).flatMap(s -> Stream.of(
n != m ? "0" + s + "0" : "",
"1" + s + "1",
"6" + s + "9",
"8" + s + "8",
"9" + s + "6"
)).filter(s -> !s.isEmpty());
}
public static void main(String[] args) {
StrobogrammaticNumberIIStream solution = new StrobogrammaticNumberIIStream();
System.out.println(solution.findStrobogrammatic(2));
}
}
解释
方法:
这个题解使用了深度优先搜索(DFS)的思路来生成中心对称数。首先,对于长度为0和1的中心对称数,直接返回对应的结果。对于长度大于1的中心对称数,通过递归生成长度减2的中心对称数,然后在两边添加对称的数字对(11、88、69、96)得到新的中心对称数。特别地,如果当前生成的中心对称数长度不等于目标长度n,还可以在两边添加00得到新的中心对称数。最终返回长度为n的所有中心对称数。
时间复杂度:
O(5^(n/2))
空间复杂度:
O(n * 5^(n/2))
代码细节讲解
🦆
在解决这个问题时,为什么选择使用深度优先搜索(DFS)而不是其他可能的算法,例如广度优先搜索(BFS)或动态规划?
▷🦆
在递归函数中,将'00'添加到结果中只在`u != n`的条件下进行。这是基于什么考虑?是否是为了避免在生成最终长度为n的中心对称数时出现以0开头的非法数字?
▷🦆
题解提到,中心对称数的生成依赖于添加对称的数字对(11、88、69、96),那么在选择这些对称的数字对时,有没有考虑到它们在数学或编程上的特殊性质,这些性质是什么?
▷🦆
在实际实现中,递归深度为O(n)可能会导致栈溢出。有没有可能的优化策略来减少递归的深度或是完全避免递归?
▷