Skip to content

Commit 14691c5

Browse files
committed
add notes
1 parent 2a894a6 commit 14691c5

7 files changed

Lines changed: 527 additions & 0 deletions

File tree

Algorithm/34.有效的数独.md

Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
34.有效的数独
2+
===
3+
4+
5+
### 题目
6+
7+
请你判断一个 9 x 9 的数独是否有效。只需要 根据以下规则 ,验证已经填入的数字是否有效即可。
8+
9+
数字 1-9 在每一行只能出现一次。
10+
数字 1-9 在每一列只能出现一次。
11+
数字 1-9 在每一个以粗实线分隔的 3x3 宫内只能出现一次。(请参考示例图)
12+
13+
14+
注意:
15+
16+
- 一个有效的数独(部分已被填充)不一定是可解的。
17+
- 只需要根据以上规则,验证已经填入的数字是否有效即可。
18+
- 空白格用 '.' 表示。
19+
20+
21+
22+
![image](https://raw.githubusercontent.com/CharonChui/Pictures/master/isValidSudoku.png?raw=true)
23+
24+
25+
```
26+
输入:board =
27+
[["5","3",".",".","7",".",".",".","."]
28+
,["6",".",".","1","9","5",".",".","."]
29+
,[".","9","8",".",".",".",".","6","."]
30+
,["8",".",".",".","6",".",".",".","3"]
31+
,["4",".",".","8",".","3",".",".","1"]
32+
,["7",".",".",".","2",".",".",".","6"]
33+
,[".","6",".",".",".",".","2","8","."]
34+
,[".",".",".","4","1","9",".",".","5"]
35+
,[".",".",".",".","8",".",".","7","9"]]
36+
```
37+
输出:true
38+
39+
```
40+
输入:board =
41+
[["8","3",".",".","7",".",".",".","."]
42+
,["6",".",".","1","9","5",".",".","."]
43+
,[".","9","8",".",".",".",".","6","."]
44+
,["8",".",".",".","6",".",".",".","3"]
45+
,["4",".",".","8",".","3",".",".","1"]
46+
,["7",".",".",".","2",".",".",".","6"]
47+
,[".","6",".",".",".",".","2","8","."]
48+
,[".",".",".","4","1","9",".",".","5"]
49+
,[".",".",".",".","8",".",".","7","9"]]
50+
```
51+
输出:false
52+
解释:除了第一行的第一个数字从 5 改为 8 以外,空格内其他数字均与 示例1 相同。 但由于位于左上角的 3x3 宫内有两个 8 存在, 因此这个数独是无效的。
53+
54+
55+
提示:
56+
57+
- board.length == 9
58+
- board[i].length == 9
59+
- board[i][j] 是一位数字(1-9)或者 '.'
60+
61+
62+
### 思路
63+
64+
有效的数独满足以下三个条件:
65+
66+
- 同一个数字在每一行只能出现一次;
67+
68+
- 同一个数字在每一列只能出现一次;
69+
70+
- 同一个数字在每一个小九宫格只能出现一次。
71+
72+
---
73+
74+
- i是行标
75+
- j是列标
76+
- 数字从char直接转换成int,会变成对应的ASCII数字码,而不是原来的数值。解决方法就是当前char数字减'0':用两个char数字的ASCII码相减,差值就是原来char数值直接对应的int数值。
77+
- 为什么不是减'0',而是减'1'?
78+
- 若运行了大佬的代码你会发现,减'0'的话会出现`ArrayIndexOutOfBoundsException`的异常。因为后面的代码将这个`num`作为了数组的下标。本身数组设置的就是9个位置,下标范围是`[0~8]`,那么遇到数字9作为下标的时候,不就越位了吗,所以就要减1,char转换成int的同时还能解决后面越位的情况。
79+
- boolean数组的巧妙建立
80+
- 第一个[]存放第?行/列/块
81+
- 第二个[]存放 相应数字
82+
- 结合起来解释就是:第?行/列/块 是否 出现过相应数字
83+
84+
- 行标决定一组block的起始位置(因为block为3行,所以除3取整得到组号,又因为每组block为3个,所以需要乘3),列标再细分出是哪个block(因为block是3列,所以除3取整)
85+
86+
```
87+
blockIndex = i / 3 * 3 + j / 3的原因:
88+
[0, 0, 0, 1, 1, 1, 2, 2, 2]
89+
[0, 0, 0, 1, 1, 1, 2, 2, 2]
90+
[0, 0, 0, 1, 1, 1, 2, 2, 2]
91+
[3, 3, 3, 4, 4, 4, 5, 5, 5]
92+
[3, 3, 3, 4, 4, 4, 5, 5, 5]
93+
[3, 3, 3, 4, 4, 4, 5, 5, 5]
94+
[6, 6, 6, 7, 7, 7, 8, 8, 8]
95+
[6, 6, 6, 7, 7, 7, 8, 8, 8]
96+
[6, 6, 6, 7, 7, 7, 8, 8, 8]
97+
```
98+
99+
- blockIndex的规律探寻
100+
- 微观`9x9` -> 宏观`3x3`
101+
- (1)`i/3`为行号,`j/3`为列号
102+
- (2)二维数组思路:`行号*列数+列号`,即位置
103+
104+
105+
106+
107+
```java
108+
109+
class Solution {
110+
public boolean isValidSudoku(char[][] board) {
111+
// 记录某行,某位数字是否已经被摆放
112+
boolean[][] row = new boolean[9][9];
113+
// 记录某列,某位数字是否已经被摆放
114+
boolean[][] col = new boolean[9][9];
115+
// 记录某 3x3 宫格内,某位数字是否已经被摆放
116+
boolean[][] block = new boolean[9][9];
117+
118+
for (int i = 0; i < 9; i++) {
119+
for (int j = 0; j < 9; j++) {
120+
if (board[i][j] != '.') { // 只处理数字格子
121+
int num = board[i][j] - '1';
122+
int blockIndex = i / 3 * 3 + j / 3;
123+
if (row[i][num] || col[j][num] || block[blockIndex][num]) {
124+
return false;
125+
} else {
126+
row[i][num] = true;
127+
col[j][num] = true;
128+
block[blockIndex][num] = true;
129+
}
130+
}
131+
}
132+
}
133+
return true;
134+
}
135+
}
136+
```
137+
138+
---
139+
- 邮箱 :charon.chui@gmail.com
140+
- Good Luck!
141+
142+

Algorithm/35.螺旋矩阵.md

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
35.螺旋矩阵
2+
===
3+
4+
5+
### 题目
6+
7+
8+
给你一个 m 行 n 列的矩阵 matrix ,请按照 顺时针螺旋顺序 ,返回矩阵中的所有元素。
9+
10+
11+
示例 1:
12+
![image](https://raw.githubusercontent.com/CharonChui/Pictures/master/spiralOrder_1.png?raw=true)
13+
14+
- 输入:matrix = [[1,2,3],[4,5,6],[7,8,9]]
15+
- 输出:[1,2,3,6,9,8,7,4,5]
16+
17+
示例 2:
18+
![image](https://raw.githubusercontent.com/CharonChui/Pictures/master/spiralOrder_2.png?raw=true)
19+
20+
- 输入:matrix = [[1,2,3,4],[5,6,7,8],[9,10,11,12]]
21+
- 输出:[1,2,3,4,8,12,11,10,9,5,6,7]
22+
23+
24+
提示:
25+
26+
- m == matrix.length
27+
- n == matrix[i].length
28+
- 1 <= m, n <= 10
29+
- -100 <= matrix[i][j] <= 100
30+
31+
32+
### 思路
33+
34+
- 对于这种螺旋遍历的方法,重要的是要确定上下左右四条边的位置
35+
- 初始化的时候,上边up就是0,下边down就是m-1,左边left是0,右边right是n-1。
36+
- 然后我们进行while循环
37+
- 先遍历上边第一行up ,将所有元素加入结果res,然后上边下移一位,如果此时上边大于下边,说明此时已经遍历完成了,直接break。
38+
39+
40+
```java
41+
class Solution {
42+
public List<Integer> spiralOrder(int[][] matrix) {
43+
List<Integer> res=new ArrayList<Integer>();
44+
45+
if(matrix.length==0 || matrix[0].length==0) {
46+
return res;
47+
}
48+
49+
int m = matrix.length;
50+
int n =matrix[0].length;
51+
52+
int up = 0;
53+
int down = m-1;
54+
int left = 0;
55+
int right = n-1;
56+
57+
while(true) {
58+
for(int i=left; i<=right; i++) {
59+
res.add(matrix[up][i]);
60+
}
61+
62+
if (++up > down) {
63+
break;
64+
}
65+
66+
for (int i = up; i <= down; i++) {
67+
res.add(matrix[i][right]);
68+
}
69+
70+
if (--right < left) {
71+
break;
72+
}
73+
74+
for (int i = right; i >= left; i--) {
75+
res.add(matrix[down][i]);
76+
}
77+
78+
if (--down < up) {
79+
break;
80+
}
81+
82+
for (int i = down; i >= up; i--) {
83+
res.add(matrix[i][left]);
84+
}
85+
86+
if (++left > right) {
87+
break;
88+
}
89+
}
90+
return res;
91+
}
92+
}
93+
```
94+
95+
---
96+
- 邮箱 :charon.chui@gmail.com
97+
- Good Luck!
98+
99+

0 commit comments

Comments
 (0)