leetcode 36

感觉就是遍历。

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

用数组做。

空间小时间大

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加速。

空间大时间小

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 ;
}
};

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

改成数组

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 ;
}
};

我好了

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

然后剪枝,没考虑 OxO

leetcode 36 有效的数独 哈希表 unordered_set unordersd_map 保存状态 leetcode 37 解数独的更多相关文章

  1. Leetcode之回溯法专题-37. 解数独(Sudoku Solver)

    Leetcode之回溯法专题-37. 解数独(Sudoku Solver) 编写一个程序,通过已填充的空格来解决数独问题. 一个数独的解法需遵循如下规则: 数字 1-9 在每一行只能出现一次.数字 1 ...

  2. Java实现 LeetCode 37 解数独

    37. 解数独 编写一个程序,通过已填充的空格来解决数独问题. 一个数独的解法需遵循如下规则: 数字 1-9 在每一行只能出现一次. 数字 1-9 在每一列只能出现一次. 数字 1-9 在每一个以粗实 ...

  3. [leetcode] 37. 解数独(Java)(dfs,递归,回溯)

    37. 解数独 1A 这个题其实15分钟左右就敲出来并且对了...但是由于我输错了一个数..导致我白白debug一个多小时.. 没啥难度,练递归-dfs的好题 class Solution { pri ...

  4. [LeetCode] #1# Two Sum : 数组/哈希表/二分查找/双指针

    一. 题目 1. Two SumTotal Accepted: 241484 Total Submissions: 1005339 Difficulty: Easy Given an array of ...

  5. [LeetCode] Fraction to Recurring Decimal 哈希表

    Given two integers representing the numerator and denominator of a fraction, return the fraction in ...

  6. leetcode刷题-37解数独

    题目 编写一个程序,通过已填充的空格来解决数独问题. 一个数独的解法需遵循如下规则: 数字 1-9 在每一行只能出现一次.数字 1-9 在每一列只能出现一次.数字 1-9 在每一个以粗实线分隔的 3x ...

  7. C++ 哈希表 (hashtable) 用于保存简单的数据,及数据查找,数据删除

    /*hashtable.h*/ #include<iostream> #include <string> #include<vector> using namesp ...

  8. Leetcode——37.解数独 [##]

    @author: ZZQ @software: PyCharm @file: leetcode37_solveSudoku.py @time: 2018/11/20 16:41 思路:递归回溯 首先, ...

  9. C#LeetCode刷题-哈希表

    哈希表篇 # 题名 刷题 通过率 难度 1 两数之和 C#LeetCode刷题之#1-两数之和(Two Sum) 42.8% 简单 3 无重复字符的最长子串   24.2% 中等 18 四数之和   ...

随机推荐

  1. 【开源】我和 JAP(JA Plus) 的故事

    JA Plus 故事 程序员的故事如此简单之绕不过去的开源情结 我们准备做一件伟大的事,也可以说是一件真真正正普惠的事. 絮 是的,你没有看错,就是"絮"而非"序&quo ...

  2. pg_rman的安装与使用

    1.下载对应数据库版本及操作系统的pg_rman源码 https://github.com/ossc-db/pg_rman/releases 本例使用的是centos6.9+pg10,因此下载的是pg ...

  3. uni-app开发经验分享二十一: 图片滑动解锁插件制作解析

    在开发用户模块的时候,相信大家都碰到过一个功能,图片滑动解锁后发送验证码,这里分享我用uni-app制作的一个小控件 效果如下: 需要如下图片资源 template <template> ...

  4. k8s之PV、PVC、StorageClass详解

    导读 上一篇写了共享存储的概述以及一个简单的案例演示.这一篇就写一下PV和PVC. PV是对底层网络共享存储的抽象,将共享存储定义为一种"资源",比如Node也是容器应用可以消费的 ...

  5. libuv中实现tcp服务器

    目录 1.说明 2.libuv的tcp server 3.API简介 3.1.uv_tcp_init 3.2.uv_ip4_addr 3.3.uv_tcp_bind 3.4.uv_listen 3.5 ...

  6. DDOS攻击方式总结以及免费DDOS攻击测试工具大合集

    若有雷同或者不足之处,欢迎指正交流,谢谢! DoS(Denial Of Service)攻击是指故意的攻击网络协议实现的缺陷或直接通过野蛮手段残忍地耗尽被攻击对象的资源,目的是让目标计算机或网络无法提 ...

  7. 在QML 中用javascritpt 将中文转换拼音,可以在音标

    项目需要, 今天整理了一下.在QML调用javascrit将中文汉字转换成拼音. 感觉执行效率低.下面是主要代码. 具体代码请参考QMLPinyin 代码 ```import "./piny ...

  8. 现有以下关系型数据库中的表(见表4-20表4-21和表4-22),要求将具转换为适合Hbase存储的表并插入数据。

    ① createTable(String tableName, String[] fields) 创建表,参数tableName为表的名称,字符串数组fields为存储记录各个域名称的数组.要 求当H ...

  9. 一例 Go 编译器代码优化 bug 定位和修复解析

    https://mp.weixin.qq.com/s/Tyl6dSb7mHBuqqN6WvEuaw

  10. Building a Robust Live Reloader with WebSockets and Go — Brandur Leach https://brandur.org/live-reload

    Building a Robust Live Reloader with WebSockets and Go - Brandur Leach https://brandur.org/live-relo ...