【LeetCode】Valid Sudoku && Sudoku Solver

133 篇文章 0 订阅
121 篇文章 2 订阅
1、Valid Sudoku
Total Accepted: 5188 Total Submissions: 19186 My Submissions
Determine if a Sudoku is valid, according to: Sudoku Puzzles - The Rules.
The Sudoku board could be partially filled, where empty cells are filled with the character '.'.

A partially filled sudoku which is valid.
Note:
A valid Sudoku board (partially filled) is not necessarily solvable. Only the filled cells need to be validated.
2、Sudoku Solver
Total Accepted: 4447 Total Submissions: 22063 My Submissions
Write a program to solve a Sudoku puzzle by filling the empty cells.
Empty cells are indicated by the character '.'.

You may assume that there will be only one unique solution.
A sudoku puzzle...

...and its solution numbers marked in red.
一个是验证九宫格数独,一个是填数字。
初次玩这个,应该还是在高中的时候,挺有意思。最强大脑中的孙彻然就是玩这个的,看上去很厉害的样子。作为码农来说,还是写程序解决。
1、思路:针对每一个格子,如果有数字,就需要判断同一行,同一列以及同一个小的九宫格是否有重复数字出现。直接循环扫描就可以实现。

Java AC

public class Solution {
    public boolean isValidSudoku(char[][] board) {
        int n = board.length;
        for(int i = 0; i < n; i++){
            for(int j = 0; j < n; j++){
                if(board[i][j] == '.'){
                    continue;
                }
                for(int k = 0; k < n; k++){
                	if (k == j) {
						continue;
					}
                    if(board[i][k] == board[i][j]){
//                    	System.out.println("1 "+i+" "+j );
                        return false;
                    }
                }
                for(int k = 0; k < n; k++){
                	if (k == i) {
						continue;
					}
                    if(board[k][j] == board[i][j]){
//                    	System.out.println("2 "+i+" "+j );
                        return false;
                    }
                }
                int rowStart = i / 3 * 3;
                int rowEnd = rowStart+3;
                int colStart = j / 3 * 3;
                int colEnd = colStart+3;
                for(int k = rowStart; k < rowEnd; k++){
                    for(int l = colStart; l < colEnd; l++){
                        if(k == i && l == j){
                            continue;
                        }
                        if(board[k][l] == board[i][j]){
//                        	System.out.println("3 "+i+" "+j );
                            return false;
                        }
                    }
                }
            }
        }
        return true;
    }
}
2、思路:dfs,最开始的时候考虑边界问题。后来看到某个大牛写的代码,思路还是很不错的,可以借鉴。其实就是将所有需要填数字的坐标拿出来,从1到9依次判断是否可以填写,如果不对就回溯,否则继续。最后返回true,即结束。

Java AC

public class Solution {
    public int n, size;
	public ArrayList<Integer> list;
	public void solveSudoku(char[][] board) {
		n = board.length;
		list = new ArrayList<Integer>();
		for (int i = 0; i < n; i++) {
			for (int j = 0; j < n; j++) {
				if (board[i][j] == '.') {
					list.add(i * n + j);
				}
			}
		}
		size = list.size();
		dfs(board, 0);
	}

	public boolean dfs(char[][] board, int cur) {
		if (cur == size) {
			return true;
		}
		int index = list.get(cur);
		int row = index / n;
		int col = index % n;
		for (int i = 1; i <= 9; i++) {
			if (isValidSudoku(board, row, col, (char)(i+'0'))) {
				board[row][col] = (char)(i+'0');
				if (dfs(board, cur+1)) {
					return true;
				}
				board[row][col] = '.';
			}
		}
		return false;
	}

	public boolean isValidSudoku(char[][] board, int i, int j, Character value) {
		for (int k = 0; k < n; k++) {
			if (k == j) {
				continue;
			}
			if (board[i][k] == value) {
				// System.out.println("1 "+i+" "+j );
				return false;
			}
		}
		for (int k = 0; k < n; k++) {
			if (k == i) {
				continue;
			}
			if (board[k][j] == value) {
				// System.out.println("2 "+i+" "+j );
				return false;
			}
		}
		int rowStart = i / 3 * 3;
		int rowEnd = rowStart + 3;
		int colStart = j / 3 * 3;
		int colEnd = colStart + 3;
		for (int k = rowStart; k < rowEnd; k++) {
			for (int l = colStart; l < colEnd; l++) {
				if (k == i && l == j) {
					continue;
				}
				if (board[k][l] == value) {
					// System.out.println("3 "+i+" "+j );
					return false;
				}
			}
		}
		return true;
	}
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值