LeetCode037 Sudoku Solver

详细见:leetcode.com/problems/sudoku-solver


Java Solution: github

package leetcode;

/*
 * 	解数独
 * 	方法应该是试凑和回溯
 */

public class P037_SudokuSolver {
	public static void main(String[] args) {

	}
	/*
	 * 	还有很多bug
	 */
	static class Solution {
		private boolean[][] isValidRow = new boolean[9][9];
		private boolean[][] isValidColumn = new boolean[9][9];
		private boolean[][] isValidNine = new boolean[9][9];
		private boolean isSuccess = false;

		public void solveSudoku(char[][] board) {
			for (int i = 0; i < 9; i++)
				for (int j = 0; j < 9; j++)
					if (board[i][j] != '.')
						init(board, i, j);
			solve(board, 0, 0);
		}

		private void solve(char[][] board, int i, int j) {
			if (true == isSuccess)
				return;
			if (i > 8) {
				isSuccess = true;
				return;
			}
			if (board[i][j] != '.') {
				if (j < 8)
					solve(board, i, j + 1);
				else
					solve(board, i + 1, 0);
				if (isSuccess)
					return;
			} else {
				int temp = i / 3 * 3 + j / 3;
				for (int n = 0; n < 9; n++) {
					if (!isValidColumn[j][n] && !isValidRow[i][n] && !isValidNine[temp][n]) {
						board[i][j] = (char) (n + '1');
						isValidColumn[j][n] = isValidRow[i][n] = isValidNine[temp][n] = true;
						if (j < 8)
							solve(board, i, j + 1);
						else
							solve(board, i + 1, 0);
						isValidColumn[j][n] = isValidRow[i][n] = isValidNine[temp][n] = false;
						if (isSuccess)
							return;
					}
				}
			}
		}

		private void init(char[][] board, int i, int j) {
			isValidRow[i][board[i][j] - '1'] = true;
			isValidColumn[j][board[i][j] - '1'] = true;
			isValidNine[i / 3 * 3 + j / 3][board[i][j] - '1'] = true;
		}

	}
	/*
	 * 	36 ms
	 * 	18.91%
	 */
	static class Solution2 {
		public void solveSudoku(char[][] board) {
			solveSudoku2(board);
		}
		public boolean solveSudoku2(char[][] board) {
			for (int i = 0; i < 9; ++i)
				for (int j = 0; j < 9; ++j) {
					if (board[i][j] == '.') {
						for (int k = 0; k < 9; ++k) {
							board[i][j] = (char) ('1' + k);
							if (isValid(board, i, j) && solveSudoku2(board))
								return true;
							board[i][j] = '.';
						}
						return false;
					}
				}
			return true;
		}
		private boolean isValid(char[][] board, int x, int y) {
			int i, j;
			for (i = 0; i < 9; i++)
				if (i != x && board[i][y] == board[x][y])
					return false;
			for (j = 0; j < 9; j++)
				if (j != y && board[x][j] == board[x][y])
					return false;
			for (i = 3 * (x / 3); i < 3 * (x / 3 + 1); i++)
				for (j = 3 * (y / 3); j < 3 * (y / 3 + 1); j++)
					if ((i != x || j != y) && board[i][j] == board[x][y])
						return false;
			return true;
		}
	}
}


C Solution: github

/*
    url: leetcode.com/problems/sudoku-solver/
    19ms 11.43%
*/

#include <stdio.h>
#include <stdlib.h>

#define bool int

int isValid(char** b, int x, int y) {
	int i = 0, j = 0, k = 0;
    for (k = 0; k < 9; k ++) {
        if (k != x && b[k][y] == b[x][y])
			return 0;
        if (k != y && b[x][k] == b[x][y])
			return 0;
        i = (x / 3) * 3 + k / 3;
        j = (y / 3) * 3 + k % 3;
        if ((i != x || j != y) && b[i][j] == b[x][y])
            return 0;
    }
	return 1;
}

bool solveSudoku2(char** b) {
    int i = 0, j = 0, k = 0;
	for (i = 0; i < 9; ++i)
		for (j = 0; j < 9; ++j) {
			if (b[i][j] != '.') continue;
			for (k = 0; k < 9; ++k) {
				b[i][j] = (char) ('1' + k);
				if (isValid(b, i, j) && solveSudoku2(b))
					return 1;
				b[i][j] = '.';
			}
			return 0;
		}
	return 1;
}

void solveSudoku(char** b, int rs, int cs) {
    int val = solveSudoku2(b);
    printf("answer is %d\r\n", val);
}

char* setChar(char* src, int n) {
    int i = 0;
    char* dst = (char*)malloc(sizeof(char) * (n + 1));
    for (i = 0; i <= n; i ++)
        *(dst + i) = *(src + i);
    return dst;
}

int main() {
    char** b = (char **) malloc(sizeof(char *) * 9);
    char* t = NULL, * tt = NULL;
    int rs = 9, cs = 9, i = 0, j = 0;
    b[0] = setChar("..9748...", 9);
    b[1] = setChar("7........", 9);
    b[2] = setChar(".2.1.9...", 9);
    b[3] = setChar("..7...24.", 9);
    b[4] = setChar(".64.1.59.", 9);
    b[5] = setChar(".98...3..", 9);
    b[6] = setChar("...8.3.2.", 9);
    b[7] = setChar("........6", 9);
    b[8] = setChar("...2759..", 9);
    solveSudoku(b, rs, cs);
    for (i = 0; i < 9; i ++) {
        for (j = 0; j < 9; j ++) {
            printf("%c ", b[i][j]);
        }
        printf("\r\n");
    }
    for (i = 0; i < 9; i ++)
        free(*(b + i));
    free(b);
    return 0;
}


Python Solution: github

#coding=utf-8

'''
    url: leetcode.com/problems/sudoku-solver/
    @author:     zxwtry
    @email:      zxwtry@qq.com
    @date:       2017年4月5日
    @details:    Solution: 1709ms 12.51%
'''
from jinja2._compat import unichr

class Solution(object):
    def isValid(self, b, x, y):
        x_base, y_base = (x // 3) * 3, (y // 3) * 3
        for k in range(9):
            if x != k and b[x][y]==b[k][y]:
                return False
            if y != k and b[x][y]==b[x][k]:
                return False
            new_x, new_y = x_base+(k // 3), y_base+(k % 3)
            if new_x != x and new_y != y and b[x][y] == b[new_x][new_y]:
                return False
        return True
    
    def solve(self, b):
        for x in range(9):
            for y in range(9):
                if b[x][y] != '.':continue
                for k in range(9):
                    b[x][y]=unichr(ord('1')+k)
                    if self.isValid(b, x, y)\
                    and self.solve(b):
                        return True
                    b[x][y] = '.'
                return False
        return True
    
    def solveSudoku(self, b):
        """
        :type b: List[List[str]]
        :rtype: void Do not return anything, modify b in-place instead.
        """
        self.solve(b)

if __name__ == "__main__":
    b=[list("..9748..."),\
       list("7........"),\
       list(".2.1.9..."),\
       list("..7...24."),\
       list(".64.1.59."),\
       list(".98...3.."),\
       list("...8.3.2."),\
       list("........6"),\
       list("...2759..")]
    Solution().solve(b)
    print(b)


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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值