213ms Java Prefix Sum Solution with Clear Comment(Vertical or Horizontal or L,J,7,|` directions)
\npublic int maxTrailingZeros(int[][] grid) {\n        //trailing 0, 10->1, 100->2\n        //10 = 2 * 5\n        //100 = 2*2*5*5\n        //etc.\n        //min
```\npublic int maxTrailingZeros(int[][] grid) {\n        //trailing 0, 10->1, 100->2\n        //10 = 2 * 5\n        //100 = 2*2*5*5\n        //etc.\n        //min(countOf2,countOf5);\n\t\t//Part 1: move only horizontal\n\t\t//Part 2: move only vertically\n        //Part 3: one L turn\n        //Part 4: one 7 turn\n        //Part 5: one J turn\n        //Part 6: one |` turn\n        \n\t\t//Create PrefixSum array to store count of 2 and 5, then we need O(1) time to get count of 2 or 5.\n        //matrix count of 2, in row i, from j to k (j<=k) matrix2[i+1][k+1] - matrix2[i+1][j]\n        int m = grid.length;\n        int n = grid[0].length;\n        int[][] matrix2row = new int[m+1][n+1];\n        int[][] matrix5row = new int[m+1][n+1];\n        //matrix count of 2, in col i, from j to k (j<=k) matrix[k+1][i+1] - matrix[j][i+1]\n        int[][] matrix2col = new int[m+1][n+1];\n        int[][] matrix5col = new int[m+1][n+1];\n        for(int i = 0;i<grid.length;i++){\n            // System.out.println(Arrays.toString(grid[i]));\n            for(int j = 0;j<grid[0].length;j++){\n                int count2 = count2(grid[i][j]);\n                int count5 = count5(grid[i][j]);\n                // System.out.println("grid["+i+"]"+"["+j+"]="+"grid[i][j]"+",count2:"+count2);\n                matrix2row[i+1][j+1] = matrix2row[i+1][j] + count2; \n                matrix5row[i+1][j+1] = matrix5row[i+1][j] + count5; \n            }\n        }\n        for(int j = 0;j<grid[0].length;j++){\n            for(int i = 0;i<grid.length;i++){\n                int count2 = count2(grid[i][j]);\n                int count5 = count5(grid[i][j]);\n                matrix2col[i+1][j+1] = matrix2col[i][j+1] + count2;\n                matrix5col[i+1][j+1] = matrix5col[i][j+1] + count5;\n            }\n        }\n        //Part 1: move only horizontal \n        //grid[0][0]->grid[0][n-1]\n        //grid[1][0]->grid[1][n-1]\n        //...\n        //grid[m-1][0]->grid[m-1][n-1]\n        int ans = 0;\n        for(int i = 0;i<m;i++){\n            int count2 = matrix2row[i+1][n]-matrix2row[i+1][0];\n            int count5 = matrix5row[i+1][n]-matrix5row[i+1][0];\n            ans = Math.max(ans, Math.min(count2,count5));\n        }\n        \n        //Part 2: move only vertically\n        //grid[0][0]->grid[m-1][0]\n        //grid[0][1]->grid[m-1][1]\n        //...\n        //grid[0][n-1]->grid[m-1][n-1]\n        for(int j = 0;j<n;j++){\n            int count2 = matrix2col[m][j+1] - matrix2col[0][j+1];\n            int count5 = matrix5col[m][j+1] - matrix5col[0][j+1];\n            ans = Math.max(ans, Math.min(count2,count5));\n        }\n        //Find center of + then there are 4 directions\n        for(int i = 0;i<m;i++){\n            for(int j =0;j<n;j++){\n                \n                //up (i,j) to (0,j)\n                int count2Up = matrix2col[i+1][j+1] - matrix2col[0][j+1];\n                int count5Up = matrix5col[i+1][j+1] - matrix5col[0][j+1];\n                //down (i,j) to (m-1,j)\n                int count2Down = matrix2col[m][j+1] - matrix2col[i][j+1];\n                int count5Down = matrix5col[m][j+1] - matrix5col[i][j+1];\n                //left (i,0) to (i,j)\n                int count2Left = matrix2row[i+1][j+1]-matrix2row[i+1][0];\n                int count5Left = matrix5row[i+1][j+1]-matrix5row[i+1][0];\n                //right (i,j) to (i,n-1)\n                int count2Right = matrix2row[i+1][n]-matrix2row[i+1][j];\n                int count5Right = matrix5row[i+1][n]-matrix5row[i+1][j];\n                //3.1 L turn\n                ans = Math.max(ans,Math.min(count2Up+count2Right-count2(grid[i][j]),count5Up+count5Right-count5(grid[i][j])));\n                //3.2 7 turn\n                ans = Math.max(ans,Math.min(count2Up+count2Left-count2(grid[i][j]),count5Up+count5Left-count5(grid[i][j])));\n                //3.3 |` turn\n                ans = Math.max(ans,Math.min(count2Down+count2Right-count2(grid[i][j]),count5Down+count5Right-count5(grid[i][j])));\n                //3.4 J turn\n                ans = Math.max(ans,Math.min(count2Down+count2Left-count2(grid[i][j]),count5Down+count5Left-count5(grid[i][j])));\n            }\n        }\n        return ans;\n    }\n    public int count2 (int x){\n        int count = 0;\n        while(x % 2 == 0){\n            count++;\n            x = x / 2;\n        }\n        return count;\n    }\n    \n    public int count5 (int x){\n        int count = 0;\n        while(x % 5 == 0){\n            count++;\n            x = x / 5;\n        }\n        return count;\n    }\n\t```
[]