leetcode 36 有效的数独 哈希表 unordered_set unordersd_map 保存状态 leetcode 37 解数独

摘要:
Leetcode36感觉像穿越。保存的状态表示行、列和分区按数组划分。=“.”){temp=板[i][j]-'0'-1;行[i][temp]++;列[j][temp]+;dnum=(i/3)*3+j/3;div[dnum][temp]++;ifreturnfalse;}}returntrue;}};然后我学会了使用无序设置无序贴图加速。ClassSolution{public:boolisValidSudoku{vector<unordered_set<int>>row,col,block;for{int bind=(i/3)*3+j/3;char=board[i][j];ifcontinue;ifeturnfalse;row[i]insert;col[j].insert;block[bind].inserrt;}}returntrue;}};在leetcode37做之前,百度询问它是否有解决数独的技能……OxO最后一个问题保存了行、列和块的状态。也可以在这里预订。保留的不再是它是否出现,而是可以通过使用数字回溯来完成。classSolution{public:vector<unordered_set<int>>行,列,块;voidsolveSudoku{//预处理,初始状态intt=0;unordered.set<int<tp={1,2,3,4,5,6,7,8,9};对于{row.push_back;col.push_bck;block.push_bback;}forforif(板[i][j]!=块[(i/3)*3+j/3]。end())返回true;returnfalse;}voiddfs{if{flag=1;return;}inti=cnt/9,j=cnt%9;如果{forif{row[i].eerase,col[j].eerace,block[(i/3)*3+j/3].eerash;board[i][j]='0'+k;dfs;ifreturn;否则{row[i].insert,col[j].inserrt,block[(i/3)*3+j/3].insert;board[i][j]='.';}}elsecontinue;}elsedfs;return;}};那么效率很差。。
leetcode 36

感觉就是遍历。

保存好状态,就是各行各列还有各分区divide的情况

用数组做。

空间小时间大

leetcode 36 有效的数独 哈希表 unordered_set unordersd_map 保存状态 leetcode 37 解数独第1张

class Solution {
public:
    bool isValidSudoku(vector<vector<char>>& board) {
        int row[9][9]={0},col[9][9]={0},div[9][9]={0};
        int temp=0,dnum;
    for(int i=0;i<9;i++){
        for(int j=0;j<9;j++){
            if(board[i][j]!='.'){
                temp=board[i][j]-'0'-1;
                row[i][temp]++;
                col[j][temp]++;
                dnum=(i/3)*3+j/3;
                div[dnum][temp]++;
               if(row[i][temp]==2||col[j][temp]==2||div[dnum][temp]==2)
                return false;
            }
        }
    }
    return true;
    }
};

然后

学到了用unordered_set  unordersd_map加速。

空间大时间小

leetcode 36 有效的数独 哈希表 unordered_set unordersd_map 保存状态 leetcode 37 解数独第2张

class Solution {
public:
    bool isValidSudoku(vector<vector<char>>& board) {
        vector<unordered_set<int>> row(9), col(9), block(9);
        for(int i = 0; i < 9; ++ i){
            for(int j = 0; j < 9; ++ j){
                int bindex =  (i / 3)* 3 + j / 3;
                char cur = board[i][j];
                if(cur == '.')  continue;
                if(row[i].count(cur) || col[j].count(cur) || block[bindex].count(cur))  return false;
                row[i].insert(cur);
                col[j].insert(cur);
                block[bindex].insert(cur);
            }
        }
        return true;
    }
};
leetcode 37

 做之前还百度了一下有没有解数独的技巧。。。  OxO

上一道题保存了行列块的状态,这里也可以保留,保留的不再是出现与否而是可用数字

回溯就完事了

class Solution {
public:
    vector<unordered_set<int>> row, col, block;
    void solveSudoku(vector<vector<char>>& board) {
        // 预处理,初始状态
        int t=0;
        unordered_set<int> tp={1,2,3,4,5,6,7,8,9};
        for(int i=0;i<9;i++)
            {row.push_back(tp);col.push_back(tp);block.push_back(tp);}
        for( int i = 0; i < 9; i++)
            for( int j = 0; j < 9; j++)
                if( board[i][j] != '.'){
                    t = board[i][j] - '0';
                    row[i].erase(t), col[j].erase(t), block[(i/3)*3 + j/3].erase(t); 
                }
        int flag=0;
        dfs(board,0,flag);
        if(flag==0)  //题目说明有唯一解,不会出现
            cout<<"wrong"<<endl;
    }

    bool check(vector<vector<char>>& board,int i,int j,int num){
        if(row[i].find(num)!= row[i].end()&& col[j].find(num) != col[j].end()
         && block[(i/3)*3 + j/3].find(num) != block[(i/3)*3 + j/3].end())
         return true;
        return false;
    }

    void dfs(vector<vector<char>>& board,int cnt,int &flag){
        if( cnt == 81){
            flag = 1;
            return ;
        }
        int i = cnt / 9, j = cnt % 9;
        if( board[i][j] == '.'){
            for( int k = 1; k < 10; k++)
                if(check(board, i, j, k)){
                    row[i].erase(k), col[j].erase(k), block[(i/3)*3 + j/3].erase(k);
                    board[i][j] = '0'+k;
                    dfs(board, cnt+1,flag);
                    if(flag)
                        return;
                    else{
                        row[i].insert(k), col[j].insert( k), block[(i/3)*3 + j/3].insert(k);
                        board[i][j] = '.';
                    }
                }
                else
                    continue;
        }
        else
            dfs(board, cnt+1,flag); 
        return ;
    }
};

然后效率很差。。时间和空间上

leetcode 36 有效的数独 哈希表 unordered_set unordersd_map 保存状态 leetcode 37 解数独第3张

改成数组

class Solution {
public:
    int row[10][10], col[10][10], block[10][10];
    void solveSudoku(vector<vector<char>>& board) {
        // 预处理,初始状态
        int t=0;
        for( int i = 0; i < 9; i++)
            for( int j = 1; j < 10; j++)
            {
                row[i][j]=0, col[i][j]=0, block[i][j]=0;
            }
        for( int i = 0; i < 9; i++)
            for( int j = 0; j < 9; j++)
                if( board[i][j] != '.'){
                    t = board[i][j] - '0';
                    row[i][t]=1, col[j][t]=1, block[(i/3)*3 + j/3][t]=1; 
                }
        int flag=0;
        dfs(board,0,flag);
        if(flag==0)  //题目说明有唯一解,不会出现
            cout<<"wrong"<<endl;
    }

    void dfs(vector<vector<char>>& board,int cnt,int &flag){
        if( cnt == 81){
            flag = 1;
            return ;
        }
        int i = cnt / 9, j = cnt % 9;
        if( board[i][j] == '.'){
            for( int k = 1; k < 10; k++)
                if(row[i][k]==0 && col[j][k]==0 && block[(i/3)*3 + j/3][k]==0){
                    row[i][k]=1, col[j][k]=1, block[(i/3)*3 + j/3][k]=1; 
                    board[i][j] = '0'+k;
                    dfs(board, cnt+1,flag);
                    if(flag)
                        return;
                    else{
                        row[i][k]=0, col[j][k]=0, block[(i/3)*3 + j/3][k]=0; 
                        board[i][j] = '.';
                    }
                }
                else
                    continue;
        }
        else
            dfs(board, cnt+1,flag); 
        return ;
    }
};

我好了

leetcode 36 有效的数独 哈希表 unordered_set unordersd_map 保存状态 leetcode 37 解数独第4张

然后,不传引用而是copy可以再节省一点空间

然后剪枝,没考虑 OxO

免责声明:文章转载自《leetcode 36 有效的数独 哈希表 unordered_set unordersd_map 保存状态 leetcode 37 解数独》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇Maven下载速度过慢问题已解决密码验证规则-正则表达式下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

Bzoj 2789: [Poi2012]Letters 树状数组,逆序对

2789: [Poi2012]Letters Time Limit: 20 Sec  Memory Limit: 128 MBSubmit: 278  Solved: 185[Submit][Status][Discuss] Description 给出两个长度相同且由大写英文字母组成的字符串A、B,保证A和B中每种字母出现的次数相同。 现在每次可以...

c++ 数据预处理(数据去噪,归一化)

正态分布3σ原则,把3倍方差之外的点设想为噪声数据来排除。 归一化,将数据经过处理之后限定到一定的范围内,一般都会将数据限定到[0,1]。 #include <iostream>#include <string>#include <vector>#include <algorithm>#include <...

自定义UICollectionViewLayout 实现瀑布流

今天研究了一下自定义UICollectionViewLayout。 看了看官方文档,要自定义UICollectionViewLayout,需要创建一个UICollectionViewLayout的子类。同时,可以通过一下3个方法传递布局信息、contentSize、cells的信息等。 一、继承UICollectionViewLayout,重写以下方法...

STL deque详解

英文原文:http://www.codeproject.com/Articles/5425/An-In-Depth-Study-of-the-STL-Deque-Container 绪言 这篇文章深入的角度认 识 STL deque 容器。这篇文章将讨论一些有关deque的情况,比如在何种情况下你可以用deque代替vector以取 得更好的效果。读...

hash函数查找和ASL计算

   Hash表的“查找成功的ASL”和“查找不成功的ASL” ASL指的是 平均查找时间 关键字序列:(7、8、30、11、18、9、14) 散列函数: H(Key) = (key x 3) MOD 7 装载因子: 0.7 处理冲突:线性探测再散列法 查找成功的ASL计算方法: 以下求解过程是按照“计算机统考的计算方法”,不同的老师、教材在“处理冲突”...

c++ List、Vector、Stack、Queue使用

一、List使用 引入头文件#include <list> List基本函数Lists将元素按顺序储存在链表中. 与 向量(vectors)相比, 它允许快速的插入和删除,但是随机访问却比较慢.assign() 给list赋值 back() 返回最后一个元素 begin() 返回指向第一个元素的迭代器 clear() 删除所有元素 empty(...