呃,对于一个数,奇数位的话,中间只能是018.
偶数话,00 11 88 96 69
i=3开始所有的数都基于i-2的情况构造,左右两边分别加上
0 0
1 1
8 8
9 6
6 9
i=n的最后一轮构造,不能包含0 0,因为开头不能是0,但是中间构造不能省。。
public class Solution
{
public List<String> findStrobogrammatic(int n)
{
List<String> res = new ArrayList<String>();
if(n == 0) return res;
List<List<String>> list = new ArrayList<List<String>>();
List<String> tempList = new ArrayList<String>();
tempList.add("0");
tempList.add("1");
tempList.add("8");
list.add(new ArrayList<>(tempList));
if(n == 1) return list.get(0);
tempList = new ArrayList<String>();
tempList.add("00");tempList.add("11");tempList.add("88");tempList.add("69");tempList.add("96");
list.add(new ArrayList<>(tempList));
if(n == 2)
{
list.get(1).remove(0);
return list.get(1);
}
for(int i = 3; i <= n; i++)
{
tempList = new ArrayList<String>();
List<String> midList = list.get(i-3);
for(int j = 0; j < midList.size();j++)
{
boolean last = i == n;
add(midList.get(j),tempList,last);
}
list.add(new ArrayList<>(tempList));
}
return list.get(n-1);
}
public void add(String s, List<String> tempList,boolean last)
{
if(!last)
tempList.add("0" + s + "0");
tempList.add("1" + s + "1");
tempList.add("8" + s + "8");
tempList.add("6" + s + "9");
tempList.add("9" + s + "6");
}
}
仔细想想做蠢了,没必要N个LIST,保持2个就够了,这算是bottom-up。。
甚至像题目说的recursively call就行了。。似乎是top-down?那样就是从两边往中间构造了。。。
二刷。
二刷常识用DFS来做,比一刷快一些。
其实就是一刷最后所说的从两边往中间构造。
Time Complexity: 每次有3种或者5种选择,平均4种。。 然后深度是N的一半。。所以
O(4^(n/2)) = O(2^n)?
Space Complexity:
O(2^n)
有多少结果就要构造多少个String来填充吧。。不再是extra space问题。。
public class Solution {
public List<String> findStrobogrammatic(int n) {
List<String> res = new ArrayList<>();
if (n == 0) return res;
char[] ch1 = {'0','1','8','6','9'};
char[] ch2 = {'0','1','8','9','6'};
char[] s = new char[n];
dfs(res, ch1, ch2, s, 0);
return res;
}
public void dfs(List<String> res, char[] ch1, char[] ch2, char[] s, int l) {
int r = s.length - l - 1;
if (l > r) {
res.add(String.valueOf(s));
} else if (l == r) {
for (int i = 0; i < 3; i++) {
s[l] = ch1[i];
s[r] = ch2[i];
dfs(res, ch1, ch2, s, l + 1);
}
} else {
for (int i = 0; i < 5; i++) {
if (l == 0 && i == 0) continue;
s[l] = ch1[i];
s[r] = ch2[i];
dfs(res, ch1, ch2, s, l + 1);
}
}
}
}
然后一刷的办法其实也可以改进,就是先做出1和2两种长度的,然后n的长度是基于n-2的长度两边分别添加01689,最后返还的时候要去掉是0开头的。。不能直接不添加,否则会影响后面的结果。