leetcode 数独是否合法与解数独

看到解数独就想到了N皇后问题,关键点是如何将题目中的合法条件转换为代码

题目: 36. 有效的数独链接
在这里插入图片描述

思路
首先我先考虑的是如何,如何满足题目中的三个条件。刚开始想到用unordered_map<int,set> 后来发现其实可以用数组来存;
数字 1-9 在每一行只能出现一次。
数字 1-9 在每一列只能出现一次。
数字 1-9 在每一个以粗实线分隔的 3x3 宫内只能出现一次。

1.“行”:重复判断:raw[0]代表第0行的一类的数 raw[0][1] 代表着第0行值为1的数是否已经存在

vector<vector<bool>> raw(9,vector<bool> (10,false));

2.同理“列”重复判断

vector<vector<bool>> batch(9,vector<bool>(10,false));

3."块”重复判断:这个比较难理解了。就是每batch【0】(对应的是9题目中的九个块中的一个块),batch【0】【1】代表着第0块值为1的数是否已经存在

vector<vector<bool>> batch(9,vector<bool>(10,false));

代码:

class Solution {

private:


public:
    bool isValidSudoku(vector<vector<char>>& board) {
        
        vector<vector<bool>> raw(9,vector<bool> (10,false));//raw[0]代表第0行的一类的数  raw[0][1] 代表着第0行值为1的数是否已经存在

        vector<vector<bool>> col(9,vector<bool> (10,false));//同理

        vector<vector<bool>> batch(9,vector<bool>(10,false));//这个比较难理解了。就是每batch【0】(对应的是9题目中的九个块中的一个块),batch【0】【1】代表着第0块值为1的数是否已经存在

        //上面其实每个元素的集合可以存十个数,但是原题目的数字是1-9,是为了使得数字比较好计算,1放在某个数组中1号位置,2放在某个数组中的2好位置

        for(int i=0;i<board.size();i++)

            for(int j=0;j<board[0].size();j++)
            {
                if(board[i][j]=='.') continue;


                int value=board[i][j]-'0';
                int bactch_value=(i/3)*3 +j/3;
                if(raw[i][value]==true||col[j][value]==true||batch[bactch_value][value]==true) return false;
                else
                {
                    raw[i][value]=true;
                    col[j][value]=true;
                    batch[bactch_value][value]=true;
                }

            }

            return true;
    }

};

题目:37. 解数独 链接

在这里插入图片描述

思路:

代码:

class Solution {

private:
	
	//vector<vector<bool>> used(9, vector<bool>(9, false));

	vector<vector<bool> > row ;//

	vector<vector<bool> > col ;//

	vector<vector<bool> > batch;




	bool isLegal(vector<vector<char>>&board, int current_i, int current_j)
	{
		int value = board[current_i][current_j] - '0';
		int batch_index = (current_i / 3) * 3 + current_j / 3;

		if (row[current_i][value] == true || col[current_j][value] == true || batch[batch_index][value] == true) return false;//都已经存在

		return true;

	}

	bool dfs(vector<vector<char>>&board, vector<vector<bool>>&used, int start_i, int start_j)
	{
        //cout<<"start_i="<<start_i<<"   start_j="<<start_j<<"   board[start_i][start_j]="<<board[start_i][start_j]<<"  used[start_i][start_j]="<<used[start_i][start_j]<<endl;
		

		if (start_j == board[0].size())
		{
            //cout<<"开始了下一行判断"<<endl;
            //cout<<"zjs"<<endl;
			start_i = start_i + 1;
			start_j = 0;
		}
        if (start_i >= board.size()) 
        {
            cout<<"找到哦了"<<endl;
            //cout<<board[0][2]<<"  "<<board[0][3]<<"  "<<board[0][3]<<endl;
            return true;//这个代表着行到达了最后也就是全部数字填完了
        } 


        if(used[start_i][start_j] == false)  
        {
            for (int i = 1;i <= 9;i++)//也就是每个位置都可以是1 -9之间的数字
            {
                //cout<<"1"<<endl;
            
                board[start_i][start_j] = i + '0';
                //cout<<"currentV="<<board[start_i][start_j]<<endl;
                if ( isLegal(board, start_i, start_j))
                {
                    //cout<<"2"<<endl;
                    int value = i;
		            int batch_index = (start_i / 3) * 3 + start_j / 3;

                    // cout<<"数字填充start_i="<<start_i<<"   start_j="<<start_j<<"   board[start_i][start_j]="<<board[start_i][start_j]<<endl;
                     //cout<<"数字填充row[start_i][value]="<<row[start_i][value]<<"  col[start_j][value]="<<col[start_j][value]<<"  batch[batch_index][value]="<<batch[batch_index][value]<<endl;
                    //used[start_i][start_j]==false 这个代表着某些题目已知的数字不能动

                    row[start_i][value] = true;//
                    col[start_j][value] = true;

                 

                    batch[batch_index][value] = true;


                    if (dfs(board, used, start_i, start_j+1)) return true;//找到了才返回,不然接着继续找

                    row[start_i][value]=false;
                    col[start_j][value] = false;
                    batch[batch_index][value] = false;



                }
            }

        }else
        {
            //cout<<"3"<<endl;
             if (dfs(board, used, start_i, start_j+1)) return true;
          //return dfs(board, used, start_i, start_j+1);
        }
		


		return false;

	}


public:
	void solveSudoku(vector<vector<char>>& board)
	{
		row= vector<vector<bool> > (9, vector<bool>(10, false));
		col = vector<vector<bool> >(9, vector<bool>(10, false));
		batch = vector<vector<bool> >(9, vector<bool>(10, false));
		
		
		vector<vector<bool>> used(9, vector<bool>(9, false));
		for (int i = 0;i < board.size();i++)
		{
			for (int j = 0;j < board[0].size();j++)
			{
				if (board[i][j] == '.') continue;

				int value = board[i][j] - '0';//取值范围时【1,9】之间
                //cout<<"value="<<value<<endl;
				row[i][value] = true;//
				col[j][value] = true;

				int batch_index = (i / 3) * 3 + j / 3;

				batch[batch_index][value] = true;

				used[i][j] = true;

			}

			

		}

       
        int start_i = 0;
        int start_j = 0;

        dfs(board, used, start_i, start_j);




	}
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值