大白的故事 大白的故事
首页
  • 学习笔记

    • LeetCode题解导航
  • 学习笔记

    • TypeScript笔记
页面
技术
  • 友情链接
关于
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
dbdgs

大白的故事

终身学习者
首页
  • 学习笔记

    • LeetCode题解导航
  • 学习笔记

    • TypeScript笔记
页面
技术
  • 友情链接
关于
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • leetcode

    • LeetCode题解
    • leetcode1 两数之和[简单难度]
    • leetcode2 Add Two Numbers
    • leetcode3 Longest Substring Without Repeating Characters
    • leetcode4 寻找两个正序数组的中位数[困难难度]
    • leetcode5 Longest Palindromic Substring
    • leetcode6 ZigZag Conversion
    • leetcode7 Reverse Integer
    • leetcode8 String to Integer (atoi)
    • leetcode9 Palindrome Number
    • leetcode10 Regular Expression Matching
    • leetcode11-盛最多水的容器[中等难度]
    • leetcode12 Integer to Roman
    • leetcode13 Roman to Integer
    • leetcode14 Longest Common Prefix
    • leetcode15 3Sum
    • leetcode16 3Sum Closest
    • leetcode17 Letter Combinations of a Phone Number
    • leetcode18 4Sum
    • leetcode19 Remove Nth Node From End of List
    • leetcode20 Valid Parentheses
    • leetcode21 Merge Two Sorted Lists
    • leetcode22 Generate Parentheses
    • leetcode23 Merge k Sorted Lists
    • leetcode24 Swap Nodes in Pairs
    • leetcode25 Reverse Nodes in k-Group
    • leetcode26 Remove Duplicates from Sorted Array
    • leetcode27 Remove Element
    • leetcode28 Implement strStr()
    • leetcode29 Divide Two Integers
    • leetcode30 Substring with Concatenation of All Words
    • leetcode31 Next Permutation
    • leetcode32 Longest Valid Parentheses
    • leetcode33 Search in Rotated Sorted Array
    • leetcode34 Find First and Last Position of Element in Sorted Array
    • leetcode35 Search Insert Position
    • leetcode36 有效的数独[中等难度]
      • 分析
        • 方法1、蛮力直接法
        • 方法2:set插入方法 - 改进
        • 方法3:使用位操作
    • leetcode37 Sudoku Solver
    • leetcode38 外观数列(报数)【中等难度】
    • leetcode39 Combination Sum
    • leetcode40 Combination Sum II
    • leetcode41 First Missing Positive-zh
    • leetcode42 Trapping Rain Water-zh
    • leetcode43 Multiply Strings-zh
    • leetcode44 Wildcard Matching-zh
    • leetcode45 Jump Game II-zh
    • leetcode46 Permutations-zh
    • leetcode47 Permutations II-zh
    • leetcode48 Rotate Image-zh
    • leetcode49 Group Anagrams-zh
    • leetcode50 Pow(x, n)-zh
    • leetcode51 N-Queens-zh
    • leetcode52 N-Queens II-zh
    • leetcode53 Maximum Subarray-zh
    • leetcode54 Spiral Matrix-zh
    • leetcode55 Jump Game-zh
    • leetcode56 Merge Intervals-zh
    • leetcode57 Insert Interval-zh
    • leetcode58 Length of Last Word-zh
    • leetcode59 Spiral Matrix II-zh
    • leetcode60 Permutation Sequence-zh
    • leetcode61 Rotate List-zh
    • leetcode62 Unique Paths-zh
    • leetcode63 Unique Paths II-zh
    • leetcode64 Minimum Path Sum-zh
    • leetcode65 Valid Number-zh
    • leetcode66 Plus One-zh
    • leetcode67 Add Binary-zh
    • leetcode68 Text Justification-zh
    • leetcode69 Sqrt(x)-zh
    • leetcode70 Climbing Stairs-zh
    • leetcode71 Simplify Path-zh
    • leetcode72 Edit Distance-zh
    • leetcode73 Set Matrix Zeroes-zh
    • leetcode74 Search a 2D Matrix-zh
    • leetcode75 Sort Colors-zh
    • leetcode76 Minimum Window Substring-zh
    • leetcode77 Combinations-zh
    • leetcode78 Subsets-zh
    • leetcode79 Word Search-zh
    • leetcode80 Remove Duplicates from Sorted Array II-zh
    • leetcode81 Search in Rotated Sorted Array II-zh
    • leetcode82 Remove Duplicates from Sorted List II-zh
    • leetcode83 Remove Duplicates from Sorted List-zh
    • leetcode84 Largest Rectangle in Histogram-zh
    • leetcode85 Maximal Rectangle-zh
    • leetcode86 Partition List-zh
    • leetcode87 Scramble String-zh
    • leetcode88 Merge Sorted Array-zh
    • leetcode89 Gray Code-zh
    • leetcode90 Subsets II-zh
    • leetcode91 Decode Ways-zh
    • leetcode92 Reverse Linked List II-zh
    • leetcode93 Restore IP Addresses-zh
    • leetcode94 Binary Tree Inorder Traversal-zh
    • leetcode95 Unique Binary Search Trees II-zh
    • leetcode96 Unique Binary Search Trees-zh
    • leetcode97 Interleaving String-zh
    • leetcode98 Validate Binary Search Tree-zh
    • leetcode99 Recover Binary Search Tree-zh
    • leetcode100 Same Tree-zh
    • leetcode101 Symmetric Tree-zh
    • leetcode102 Binary Tree Level Order Traversal-zh
    • leetcode103 Binary Tree Zigzag Level Order Traversal-zh
    • leetcode104 Maximum Depth of Binary Tree-zh
    • leetcode105 Construct Binary Tree from Preorder and Inorder Traversal-zh
    • leetcode106 Construct Binary Tree from Inorder and Postorder Traversal-zh
    • leetcode107 Binary Tree Level Order Traversal II-zh
    • leetcode108 Convert Sorted Array to Binary Search Tree-zh
    • leetcode109 Convert Sorted List to Binary Search Tree-zh
    • leetcode110 Balanced Binary Tree-zh
    • leetcode111 Minimum Depth of Binary Tree-zh
    • leetcode112 Path Sum-zh
    • leetcode113 Path Sum II-zh
    • leetcode114 Flatten Binary Tree to Linked List-zh
    • leetcode115 Distinct Subsequences-zh
    • leetcode116 Populating Next Right Pointers in Each Node-zh
    • leetcode117 Populating Next Right Pointers in Each Node II-zh
    • leetcode118 Pascal's Triangle-zh
    • leetcode119 Pascal's Triangle II-zh
    • leetcode120 Triangle-zh
    • leetcode121 Best Time to Buy and Sell Stock-zh
    • leetcode122 Best Time to Buy and Sell Stock II-zh
    • leetcode123 Best Time to Buy and Sell Stock III-zh
    • leetcode124 Binary Tree Maximum Path Sum-zh
    • leetcode125 Valid Palindrome-zh
    • leetcode126 Word Ladder II-zh
    • leetcode127 Word Ladder-zh
    • leetcode128 Longest Consecutive Sequence-zh
    • leetcode129 Sum Root to Leaf Numbers-zh
    • leetcode130 Surrounded Regions-zh
    • leetcode131 Palindrome Partitioning-zh
    • leetcode132 Palindrome Partitioning II-zh
    • leetcode133 Clone Graph-zh
    • leetcode134 Gas Station-zh
    • leetcode135 Candy-zh
    • leetcode136 Single Number-zh
    • leetcode137 Single Number II-zh
    • leetcode138 Copy List with Random Pointer-zh
    • leetcode139 Word Break-zh
    • leetcode140 Word Break II-zh
    • leetcode141 Linked List Cycle-zh
    • leetcode142 Linked List Cycle II-zh
    • leetcode143 Reorder List-zh
    • leetcode144 Binary Tree Preorder Traversal-zh
    • leetcode145 Binary Tree Postorder Traversal-zh
    • leetcode146 Lru Cache-zh
    • leetcode147 Insertion Sort List-zh
    • leetcode148 Sort List-zh
    • leetcode149 Max Points on a Line-zh
    • leetcode150 Evaluate Reverse Polish Notation-zh
    • leetcode151 Reverse Words in a String-zh
    • leetcode152 Maximum Product Subarray-zh
    • leetcode153 Find Minimum in Rotated Sorted Array-zh
    • leetcode154 Find Minimum in Rotated Sorted Array II-zh
    • leetcode155 Min Stack-zh
    • leetcode156 Binary Tree Upside Down-zh
    • leetcode157 Read N Characters Given Read4-zh
    • leetcode158 Read N Characters Given Read4 II - Call multiple times-zh
    • leetcode159 Longest Substring with At Most Two Distinct Characters-zh
    • leetcode160 Intersection of Two Linked Lists-zh
    • leetcode161 One Edit Distance-zh
    • leetcode162 Find Peak Element-zh
    • leetcode163 Missing Ranges-zh
    • leetcode164 Maximum Gap-zh
    • leetcode165 Compare Version Numbers-zh
    • leetcode166 Fraction to Recurring Decimal-zh
    • leetcode167 Two Sum II - Input array is sorted-zh
    • leetcode168 Excel Sheet Column Title-zh
    • leetcode169 Majority Element-zh
    • leetcode170 Two Sum III - Data structure design-zh
    • leetcode171 Excel Sheet Column Number-zh
    • leetcode172 Factorial Trailing Zeroes-zh
    • leetcode173 Binary Search Tree Iterator-zh
    • leetcode174 Dungeon Game-zh
    • leetcode175 Combine Two Tables-zh
    • leetcode176 Second Highest Salary-zh
    • leetcode177 Nth Highest Salary-zh
    • leetcode178 Rank Scores-zh
    • leetcode179 Largest Number-zh
    • leetcode180 Consecutive Numbers-zh
    • leetcode181 Employees Earning More Than Their Managers-zh
    • leetcode182 Duplicate Emails-zh
    • leetcode183 Customers Who Never Order-zh
    • leetcode184 Department Highest Salary-zh
    • leetcode185 Department Top Three Salaries-zh
    • leetcode186 Reverse Words in a String II-zh
    • leetcode187 Repeated DNA Sequences-zh
    • leetcode188 Best Time to Buy and Sell Stock IV-zh
    • leetcode189 Rotate Array-zh
    • leetcode190 Reverse Bits-zh
    • leetcode191 Number of 1 Bits-zh
    • leetcode192 Word Frequency-zh
    • leetcode193 Valid Phone Numbers-zh
    • leetcode194 Transpose File-zh
    • leetcode195 Tenth Line-zh
    • leetcode196 Delete Duplicate Emails-zh
    • leetcode197 Rising Temperature-zh
    • leetcode198 House Robber-zh
    • leetcode199 Binary Tree Right Side View-zh
    • leetcode200 Number of Islands-zh
    • leetcode201 Bitwise AND of Numbers Range-zh
    • leetcode202 Happy Number-zh
    • leetcode203 Remove Linked List Elements-zh
    • leetcode204 Count Primes-zh
    • leetcode205 Isomorphic Strings-zh
    • leetcode206 Reverse Linked List-zh
    • leetcode207 Course Schedule-zh
    • leetcode208 Implement Trie (Prefix Tree)-zh
    • leetcode209 Minimum Size Subarray Sum-zh
    • leetcode210 Course Schedule II-zh
    • leetcode211 Design Add and Search Words Data Structure-zh
    • leetcode212 Word Search II-zh
    • leetcode213 House Robber II-zh
    • leetcode214 Shortest Palindrome-zh
    • leetcode215 Kth Largest Element in an Array-zh
    • leetcode216 Combination Sum III-zh
    • leetcode217 Contains Duplicate-zh
    • leetcode218 The Skyline Problem-zh
    • leetcode219 Contains Duplicate II-zh
    • leetcode220 Contains Duplicate III-zh
    • leetcode221 Maximal Square-zh
    • leetcode222 Count Complete Tree Nodes-zh
    • leetcode223 Rectangle Area-zh
    • leetcode224 Basic Calculator-zh
    • leetcode225 Implement Stack using Queues-zh
    • leetcode226 Invert Binary Tree-zh
    • leetcode227 Basic Calculator II-zh
    • leetcode228 Summary Ranges-zh
    • leetcode229 Majority Element II-zh
    • leetcode230 Kth Smallest Element in a BST-zh
    • leetcode231 Power of Two-zh
    • leetcode232 Implement Queue using Stacks-zh
    • leetcode233 Number of Digit One-zh
    • leetcode234 Palindrome Linked List-zh
    • leetcode235 Lowest Common Ancestor of a Binary Search Tree-zh
    • leetcode236 Lowest Common Ancestor of a Binary Tree-zh
    • leetcode237 Delete Node in a Linked List-zh
    • leetcode238 Product of Array Except Self-zh
    • leetcode239 Sliding Window Maximum-zh
    • leetcode240 Search a 2D Matrix II-zh
    • leetcode241 Different Ways to Add Parentheses-zh
    • leetcode242 Valid Anagram-zh
    • leetcode243 Shortest Word Distance-zh
    • leetcode244 Shortest Word Distance II-zh
    • leetcode245 Shortest Word Distance III-zh
    • leetcode246 Strobogrammatic Number-zh
    • leetcode247 Strobogrammatic Number II-zh
    • leetcode248 Strobogrammatic Number III-zh
    • leetcode249 Group Shifted Strings-zh
    • leetcode250 Count Univalue Subtrees-zh
    • leetcode251 Flatten 2D Vector-zh
    • leetcode252 Meeting Rooms-zh
    • leetcode253 Meeting Rooms II-zh
    • leetcode254 Factor Combinations-zh
    • leetcode255 Verify Preorder Sequence in Binary Search Tree-zh
    • leetcode256 Paint House-zh
    • leetcode257 Binary Tree Paths-zh
    • leetcode258 Add Digits-zh
    • leetcode259 3Sum Smaller-zh
    • leetcode260 Single Number III-zh
  • leetcode-p2

  • 算法
  • leetcode
geekzl.com
2021-07-17

leetcode36 有效的数独【中等难度】|极客学长

# 36. 有效的数独 (opens new window)

# 英文题目: Valid sudoku

  ●  难度: 中等

请你判断一个 9x9 的数独是否有效。只需要 根据以下规则 ,验证已经填入的数字是否有效即可。

  1. 数字 1-9 在每一行只能出现一次。
  2. 数字 1-9 在每一列只能出现一次。
  3. 数字 1-9 在每一个以粗实线分隔的 3x3 宫内只能出现一次。(请参考示例图)

数独部分空格内已填入了数字,空白格用 '.' 表示。

注意:

  • 一个有效的数独(部分已被填充)不一定是可解的。
  • 只需要根据以上规则,验证已经填入的数字是否有效即可。

示例 1:

img

输入:board = 
[["5","3",".",".","7",".",".",".","."]
,["6",".",".","1","9","5",".",".","."]
,[".","9","8",".",".",".",".","6","."]
,["8",".",".",".","6",".",".",".","3"]
,["4",".",".","8",".","3",".",".","1"]
,["7",".",".",".","2",".",".",".","6"]
,[".","6",".",".",".",".","2","8","."]
,[".",".",".","4","1","9",".",".","5"]
,[".",".",".",".","8",".",".","7","9"]]
输出:true
1
2
3
4
5
6
7
8
9
10
11

示例 2:

输入:board = 
[["8","3",".",".","7",".",".",".","."]
,["6",".",".","1","9","5",".",".","."]
,[".","9","8",".",".",".",".","6","."]
,["8",".",".",".","6",".",".",".","3"]
,["4",".",".","8",".","3",".",".","1"]
,["7",".",".",".","2",".",".",".","6"]
,[".","6",".",".",".",".","2","8","."]
,[".",".",".","4","1","9",".",".","5"]
,[".",".",".",".","8",".",".","7","9"]]
输出:false
解释:除了第一行的第一个数字从 5 改为 8 以外,空格内其他数字均与 示例1 相同。 但由于位于左上角的 3x3 宫内有两个 8 存在, 因此这个数独是无效的。
1
2
3
4
5
6
7
8
9
10
11
12

提示:

  • board.length == 9
  • board[i].length == 9
  • board[i][j] 是一位数字或者 '.'

# 分析

# 方法1、蛮力直接法

使用set, 对于行遍历: 每一行中, isValid: unique的数字数量+'.'的数量 = 9, 对于列遍历:每一列中, isValid: unique的数字数量+'.'的数量 = 9, 对于box遍历:每个3行3列九宫格中,isValid: unique的数字数量+'.'的数量 = 9。


已AC代码:

class Solution {
public:
    bool isValidSudoku(vector<vector<char>> &board)
    {
        bool isValid = true;

        // 遍历行
        for (int i = 0; i < 9; i++)
        {
            set<char> st;
            vector<char> rowVec = board[i];
            int dotCount = 0;
            for (int k = 0; k < 9; k++)
            {
                if (rowVec[k] == '.')
                {
                    dotCount++;
                }
                else
                    st.insert(rowVec[k]);
            }
            int uniqueCharCount = st.size();
            if (uniqueCharCount + dotCount != 9)
            {
                isValid = false;
            }
        }

        // 遍历列
        for (int i = 0; i < 9; i++)
        {
            set<char> st;            
            int dotCount = 0;
            for (int k = 0; k < 9; k++)
            {
                if (board[k][i] == '.')
                {
                    dotCount++;
                }
                else
                    st.insert(board[k][i]);
            }
            int uniqueCharCount = st.size();
            if (uniqueCharCount + dotCount != 9)
            {
                isValid = false;
            }
        }

        // 遍历小grid: 数字 1-9 在每一个以粗实线分隔的 3x3 宫内只能出现一次。
        for (int si = 0; si <= 6; si += 3)                 
            for (int sj = 0; sj <= 6; sj += 3)
            {
                set<char> st; 
                int dotCount = 0;
                for (int i = si; i < si + 3; i++)
                {
                    for (int j = sj; j < sj + 3; j++)
                    {
                        if (board[i][j] == '.')
                            dotCount += 1;
                        else
                            st.insert(board[i][j]);
                    }
                }
                if (st.size() + dotCount != 9)
                    isValid = false;
            }
        return isValid;
    }
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71

跟国外的小伙伴想到一块去了。 https://leetcode.com/problems/valid-sudoku/discuss/869625/easy-C%2B%2B-with-set (opens new window)


# 方法2:set插入方法 - 改进

坐标中任意一点(i,j),可以map到对应的的第几行第几列的方块(box)中,box的坐标为(i/3, j/3)。

于是把一个小的九宫格中的数全压缩到一个box中,比如:

是否有插入失败的1


以最中间那个九宫格为例,使用int型的/3可以得到:

是否有插入失败的2

对于任意一个值不为'.'的字符,进行如下操作:

1.把所在row的信息插入到大九宫格中;

2.把所在column的信息插入到大九宫格中;

3.把所在的小方块(box)的信息插入到大九宫格中。

插入如果失败说明出现了重复。

# 已AC的C++代码:

class Solution {
public:
    bool isValidSudoku(vector<vector<char>>& board) {
        set<string> st;
        for (int i = 0; i < 9; i++) {
            for (int j = 0; j < 9; j++) {
                char ch = board[i][j];
                // 使用i / 3 + "," + j / 3 得到对应第几行第几列的方块(box)
                if (ch != '.'){
                    string val;
                    val.push_back(ch);
                    /* 对于任意一个值不为'.'的字符
                       1.把所在row的信息插入到大九宫格中;
                       2.把所在column的信息插入到大九宫格中;
                       3.把所在的小方块(box)的信息插入到大九宫格中。
                       插入如果失败说明出现了重复。 */
                    if (!st.insert(val + " in row " + to_string(i)).second ||
                        !st.insert(val + " in column " + to_string(j)).second ||
                        !st.insert(val + " in box " + to_string(i / 3) + "," + to_string(j / 3)).second)
                        return false;  /* set插入失败时,表示出现了重复 */
                }
            }
        }
        return true;        
    }
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26

Java的HashSet有同样的写法,Java中插入失败,会出现 set.Add() == false。

# 方法3:使用位操作

此题,使用位操作,是几种解法中速度最快的算法了。

具体做法是:

方法3

将大数独棋盘分成9个小棋盘,编号0~8。

窗口中的每个小方格若有数字,必为 1 ~ 9 (记作k),该方法适用于 遍历行/遍历列/遍历box。

然后把 二进制数 1 左移 k 位,得到偏移量shift,后续使用按位或|来判断是否存在。

# 已AC的C++代码:

class Solution {
public:
	bool isValidSudoku(vector<vector<char>>& board) {
		vector<int> row(9); // row[j]表示第j 行的9个数字各自的存在情况,同理于col, boxes
		vector<int> col(9);
		vector<int> boxes(9);

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

				shiftInt = 1 << (board[i][j] - '0');  // 转为二进制,移位结束后目标位为1,其他位均为0
				/* 每个格子若有数字,必为 1 ~ 9,该方法适用于 遍历行/遍历列/遍历box  */
				int boxPos = (i / 3) * 3 + j / 3; //将大数独棋盘分成9个小棋盘,编号0~8

				// 如果当前数字shiftInt在row[j] 或col[i] 或 boxes中已经存在,&运算后不为0,
				// 只有当前数字没出现过,&运算后为0
				if ((col[i] & shiftInt) != 0 || (row[j] & shiftInt) != 0 || (boxes[boxPos] & shiftInt) != 0)
					return false;

				//第 n 位代表 n 这个数字是否存在(1→存在, 0→不存在),同理于col[i]  boxes[boxPos]
				row[j] |= shiftInt;
				col[i] |= shiftInt;
				boxes[boxPos] |= shiftInt;
			}
		}
		return true;
	}
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33

后两种方法,参考:

https://leetcode-cn.com/problems/valid-sudoku/solution/wei-yun-suan-qiu-jie-you-xiao-shu-du-c-b-sac7/ (opens new window)

https://www.youtube.com/watch?v=ceOLAY4XUOw&ab_channel=JacobHuang (opens new window)

编辑 (opens new window)
#leetcode
上次更新: 2021/10/30, 12:58:38
leetcode35 Search Insert Position
leetcode37 Sudoku Solver

← leetcode35 Search Insert Position leetcode37 Sudoku Solver→

最近更新
01
leetcode2 Add Two Numbers
07-19
02
leetcode3 Longest Substring Without Repeating Characters
07-19
03
leetcode5 Longest Palindromic Substring
07-19
更多文章>
Theme by Vdoing | Copyright © 2020 大白的故事 | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式