• 351. Android Unlock Patterns


    最后更新

    三刷
    15-Jan-2017

    好熟悉的题了,DFS做,注意比如1-3是经过2的,如果2被访问过,那么1-3也是可以的。

    public class Solution {
        public int numberOfPatterns(int m, int n) {
            int[][] path = new int[10][10];
            boolean[] visited = new boolean[10];
            
            /*
            | 1 | 2 | 3 |
            | 4 | 5 | 6 |
            | 7 | 8 | 9 |
            */
            path[1][3] = path[3][1] = 2;
            path[1][7] = path[7][1] = 4;
            path[3][9] = path[9][3] = 6;
            path[9][7] = path[7][9] = 8;
            
            path[1][9] = path[9][1] = 5;
            path[2][8] = path[8][2] = 5;
            path[3][7] = path[7][3] = 5;
            path[4][6] = path[6][4] = 5;
    
            int res = 0;
            
            for (int i = m; i <= n; i++) {
                res += 4 * dfs(i - 1, path, visited, 1);
                res += 4 * dfs(i - 1, path, visited, 2);
                res += dfs(i - 1, path, visited, 5);
            }
            
            return res;
        }
        
        public int dfs(int left, int[][] path, boolean[] visited, int pos) {
            if (left == 0) {
                return 1;
            } else {
                visited[pos] = true;
                int res = 0;
                for (int i = 1; i <= 9; i++) {
                    if (visited[i]) continue;
                    if (path[i][pos] == 0 || visited[path[i][pos]]) {
                        res += dfs(left-1, path, visited, i);
                    }
                }
                visited[pos] = false;
                return res;
            }
       
        }
    }
    

    这个题我真是做得想打人了卧槽。

    题目不难,就是算组合,但是因为是3乘3的键盘,所以只需要从1和2分别开始DFS,结果乘以4,再加上5开始的DFS就行了。

    问题是这个傻逼题目的设定是,从1到8不需要经过4或者5。。。

    我TEST CASE 2,2 卡了好久好久,做得我怀疑人生了,怎么算都是
    (3+5)*4 + 8。。结果答案愣是56.

    最后发现题设里从1-8是不需要经过4或者5的,真是要报警了。

    https://discuss.leetcode.com/topic/63038/how-many-people-thought-from-1-to-8-should-visit-voth-4-and-5)

    public class Solution 
    {
        int res = 0;
        public int numberOfPatterns(int m, int n) 
        {
            
            
    
            boolean[][] visited = new boolean[3][3];
            visited[0][0] = true;
            helper(0,0,m,n,1,visited);
            
            //System.out.println(res);
            visited = new boolean[3][3];
            visited[0][1] = true;
            helper(0,1,m,n,1,visited);
            //System.out.println(res);
            
            res *= 4;
            
            visited = new boolean[3][3];
            visited[1][1] = true;
            helper(1,1,m,n,1,visited);
            
            
            return res;
            
            
        }
        
        public void helper(int m, int n, int x, int y, int c, boolean[][] visited)
        {
            if(c >= x && c <= y) res++;
            
            for(int i = 0; i < 3;i++)
                for(int j = 0; j < 3; j++)
                {
                    
                    
                    if(jumpable(visited,m,n,i,j))
                    {
                        visited[i][j] = true;
                        helper(i,j,x,y,c+1,visited);
                        visited[i][j] = false;
                        
                    }
                    
                    
                    
                }
        }
        
        
        public boolean jumpable(boolean[][] visited, int m1, int n1, int m2, int n2)
        {
            if(visited[m2][n2]) return false;
            int x = Math.abs(m1-m2);
            int y = Math.abs(n1-n2);
            
            // adjacent
            if(x <= 1 && y <= 1) return true;
            
            // di
            if(x == 2 && y == 2) return visited[1][1];
            
            // horizontal
            if(x == 0 && y == 2) return visited[m1][1];
            
            // vertical
            if(x == 2 && y == 0) return visited[1][n1];
            /*
            if(x == 1 && y == 2) return visited[m1][1] && visited[m2][1];
            if(x == 2 && y == 1) return visited[1][n1] && visited[1][n2];
            */
            return true;
            
        }
        
        
    }
    



    二刷。
    08-Nov-2016

    这个题光记得一刷的时候颇有怨念,因为跳马子格不算碰到中间2个,卡了好久
    https://discuss.leetcode.com/topic/63038/how-many-people-thought-from-1-to-8-should-visit-voth-4-and-5)

    还是以 1 2 5分别作为起点,然后1 和 2的要最后乘以4,因为1-9个数字可以转90°转3次。
    这次换了个做法,直接标记所有路径,反正也不是很多。

    Time: O(n!)
    Space: O(n^2)

    public class Solution {
        public int numberOfPatterns(int m, int n) {
            int[][] path = new int[10][10];
            /*
            | 1 | 2 | 3 |
            | 4 | 5 | 6 |
            | 7 | 8 | 9 |
            */
            path[1][3] = path[3][1] = 2;
            path[1][7] = path[7][1] = 4;
            path[3][9] = path[9][3] = 6;
            path[9][7] = path[7][9] = 8;
            path[1][9] = path[9][1] = 5;
            path[2][8] = path[8][2] = 5;
            path[3][7] = path[7][3] = 5;
            path[4][6] = path[6][4] = 5;
            int res = 0;
            boolean[] visited = new boolean[10];
            for (int i = m; i <= n; i++) {
                res += 4 * dfs(path, visited, 1, i - 1);
                res += 4 * dfs(path, visited, 2, i - 1);
                res += dfs(path, visited, 5, i - 1);
            }
            return res;
        }
        
        public int dfs(int[][] path, boolean[] visited, int cur, int left) {
            if (left == 0) {
                return 1;
            } else {
                int res = 0;
                visited[cur] = true;
                for (int i = 1; i <= 9; i++) {
                    if (visited[i]) continue;
                    if (path[cur][i] == 0 || visited[path[cur][i]]) {
                        res += dfs(path, visited, i, left - 1);
                    }
                }
                visited[cur] = false;
                return res;
            }
        }
    }
    

    一刷的办法通过坐标来判断是否经过,也不错……思考起来稍微麻烦点,实际上正解应该是一刷那种不使用N^2空间。

  • 相关阅读:
    Flex4 启动失败: 正在等待 Adobe Flash Player 连接调试器
    软件的黑盒和白盒分析方法
    PAIP.国内软件公司的现状及解决.txt
    软件逆向分析方法小结
    应用程序中主键ID生成与UUID
    JDK1.4下载 JRE1.4下载
    壳与软件保护
    数据恢复软件
    跨语言调用模块.TXT
    论文格式
  • 原文地址:https://www.cnblogs.com/reboot329/p/5958931.html
Copyright © 2020-2023  润新知