247. Strobogrammatic Number II

呃,对于一个数,奇数位的话,中间只能是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开头的。。不能直接不添加,否则会影响后面的结果。

原文地址:https://www.cnblogs.com/reboot329/p/5962690.html