36 Valid Sudoku
来源:互联网 发布:微信抢红包透视软件 编辑:程序博客网 时间:2024/06/05 10:55
接下来写两道题,Valid Sudoku 和 Sudoku Solver,分别是判断现有的九宫格是否符合要求,和 求出九宫格的解法。
Valid Sudoku 之前写过两次,第一次是很naive的写法,通过很new出一个新的array来检查duplicates的element,因为那时还不知道HashSet这么好用的东东。
第二次是用到了HashSet,并且学到一个很好用的方法,set.add() 会返回 boolean value,true代表没有出现过/添加成功,false表示已经有重复元素/添加失败。这非常好用!!但是还是有些地方可以再优化,比如我原有代码都是不管任何位置的点,都把该点所在的行列,和小方格中所有的位置都查一遍,这其实是可以优化的,因为在这之前的其实不需要查了,只要查之后的,这样应该会较大提高性能。
之前的代码如下,其实效率已经达到93%了,但是测试完今天的代码,虽然通过了,但是效率只有20-30%,回头一想,自己SB了,下面这个代码既然利用set那就是check整行,整列,整个box,一共用了9+9+9=27 次set,已经是最优解了,而我今天的方法其实还是按照 挨个 遍历的思路,没找到一个点,遍以这个点为参照去验证,实际上用了81次set,肯定慢呀。之前的高效率代码如下,其实已经非常清晰明了:
public class Solution { public boolean isValidSudoku(char[][] board) { HashSet<Character> set= new HashSet<Character>(); for(int i=0; i<9; i++){ set.clear(); for(int j=0; j<9; j++){ if( board[i][j]!= '.' && !set.add(board[i][j]) ) return false; // set.add()返回boolean,这里用在检查重复值非常巧妙 } } for(int i=0; i<9; i++){ set.clear(); for(int j=0; j<9; j++){ if( board[j][i]!= '.' && !set.add(board[j][i]) ) return false; } } for(int i=0; i<9; i+=3){ for(int j=0; j<9; j+=3){ set.clear(); for(int x=i; x<i+3; x++){ for(int y=j; y<j+3; y++){ if( board[x][y]!= '.' && !set.add(board[x][y]) ) return false; } } } } return true; } // the following code need to allocate a new array, that is maybe why the program is so slow /* public boolean hasUniElem(char [] arr){ boolean[] check = new boolean[10]; // 10 digits!! not 9 digits for(int i=0; i<arr.length; i++){ if(Character.isDigit(arr[i])){ if(check[Character.getNumericValue(arr[i])]==true) return false; else if(check[Character.getNumericValue(arr[i])]==false) check[Character.getNumericValue(arr[i])]=true; } } return true; } public char[] fetchColumn(char[][] board, int colNum){ char[] result = new char[9]; for(int i=0; i<9; i++){ result[i]=board[i][colNum]; } return result; } public char[] fetchBox(char[][] board, int rowNum, int colNum){ char[] result = new char[9]; for(int i=rowNum; i<rowNum; i++){ for(int j=colNum; j<colNum+3; j++){ result[i]=board[i][j]; } } return result; }*/}
今天的代码,效率其实不高,还是沿用了 每个点都检查 这样的 naive 思路,不提倡,还是整体考虑整行,整列,整box 更加有效
public class Solution { public boolean isValidSudoku(char[][] board) { for(int i=0; i<9; i++){ for(int j=0; j<9; j++){ if(!check(board, i, j)) return false; } } return true; } public boolean check(char[][] board, int i, int j){ HashSet<Character> set = new HashSet<>(); for(int k=j; k<9; k++){ if(board[i][k]!='.' && !set.add(board[i][k])) return false; } set.clear(); for(int k=i; k<9; k++){ if(board[k][j]!='.' && !set.add(board[k][j])) return false; } set.clear(); for(int p=i; p<i/3*3+3; p++){ for(int q=j; q<j/3*3+3; q++){ if(board[p][q]!='.' && !set.add(board[p][q])) return false; } } return true; }}
0 0
- [36]Valid Sudoku
- [leetcode 36] Valid Sudoku
- leetcode 36: Valid Sudoku
- LeetCode(36) Valid Sudoku
- leetcode-36 Valid Sudoku
- Valid Sudoku - LeetCode 36
- LeetCode 36 Valid Sudoku
- LeetCode---(36) Valid Sudoku
- Leetcode 36 Valid Sudoku
- #36 Valid Sudoku
- Leetcode[36]-Valid Sudoku
- leetcode 36: Valid Sudoku
- 36Valid Sudoku
- Leetcode# 36 Valid Sudoku
- Leetcode#36||Valid Sudoku
- 36Valid Sudoku
- 36 Valid Sudoku
- leetcode-36 Valid Sudoku
- 那些年搞不懂的术语、概念:协变、逆变、不变体
- Oracle中常见的Hint(一)
- mysql5.6加载percona版audit.log插件性能损耗压测
- Exchange Server 2007的即将生命周期,您的计划是?
- 写在最前面
- 36 Valid Sudoku
- 虚拟化
- 准备 KVM 实验环境
- 启动第一个 KVM 虚机
- CPU 和内存虚拟化原理
- KVM 存储虚拟化
- LVM 类型的 Storage Pool
- KVM 网络虚拟化基础
- 动手实践虚拟网络