1. [Leetcode 200] 岛屿的个数
解法:
- DFS:一次遍历,遇到1则进行深搜,遍历过的1设为2,遇到非1或者越界则深搜停止,统计深搜的次数,即为岛屿数量。(这里采用)
- BFS: 循环遍历每个点,如果该点是0,则跳过,如果是1,岛屿数目加1,并加入队列,并将该点改为0,避免重复访问,然后进行广搜,取出队首元素,搜索该点周围四个点,如果有1就加入队列,并将1改为0,否则就跳过,当队列空时,一块岛屿搜索完毕,进入下一块搜索。(代码可参考:岛屿的个数 BFS)
- 并查集: 将二维数组重新编号,从
0
开始,从左到右,从上到下,直到n*m-1
(其中n
为行数,m
为列数),对于位置(i,j)
则编号为i*m+j
,那么相邻(左右,上下)的为同一个值,则认为他们相通。那么最终只要统计一下father[i]==i
且对应值为1
的个数即可。(代码可参考: 岛屿的个数 Disjoint Set)
代码:
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
33class Solution {
public:
int numIslands(vector<vector<char>>& grid) {
if(grid.empty()) return 0;
int res = 0;
for(int i = 0; i < grid.size(); i++){
for(int j = 0; j < grid[0].size(); j++){
if(grid[i][j] == '1'){
dfs(grid, i, j);
res++;
}
}
}
return res;
}
void dfs(vector<vector<char>>& grid, int row, int col){
if(row < 0 || col < 0 || row >= grid.size() || col >= grid[0].size() || grid[row][col] == '0' || grid[row][col] == '2')
return;
if(grid[row][col] == '1') grid[row][col] = '2';
dfs(grid, row-1, col);
dfs(grid, row+1, col);
dfs(grid, row, col-1);
dfs(grid, row, col+1);
}
};
2. [Leetcode 77] 组合
模板题:重点在于dfs中的startPos=i+1
代码:
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
26class Solution {
public:
vector<vector<int>> combine(int n, int k) {
vector<vector<int>> res;
vector<int> inRes;
if(n<=0 || k<=0) return {};
dfs(res, inRes, n, k, 1);
return res;
}
void dfs(vector<vector<int>> &res, vector<int> &inRes, int n, int k, int startPos){
if(inRes.size()==k){
res.emplace_back(inRes);
return;
}
for(int i = startPos; i<=n; i++){
inRes.emplace_back(i);
dfs(res, inRes, n, k, i+1); //重点在于i+1
inRes.pop_back();
}
}
};
3. [Leetcode 39] 组合总和(可重复选取数字)
- 基于模板加一些改动即可,由于可重复选择数字,将startPos=i+1 改成startPos=i,判停条件满足目标和就可以了,(前提是有序数组,先拍下序)
- 代码:
1 | class Solution { |
4. [Leetcode 40] 组合总和 II (不重复)
解法:在上一题的基础上使用Set进行去重
代码:
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
30class Solution {
public:
vector<vector<int>> combinationSum2(vector<int>& candidates, int target) {
if (candidates.size() <= 0) return {};
set<vector<int>> res;
vector<int> curr;
sort(candidates.begin(), candidates.end());
dfs(res, target, 0, curr, candidates);
return vector<vector<int>>(res.begin(), res.end());
}
void dfs(set<vector<int>> &res, int target, int s, vector<int> curr, vector<int>& candidates)
{
if(target == 0)
{
res.insert(curr);
return;
}
for(int i = s; i < candidates.size(); i++)
{
if(target - candidates[i] < 0) break;
curr.emplace_back(candidates[i]);
dfs(res, target - candidates[i], i+1, curr, candidates);
curr.pop_back();
}
}
};
5.[Leetcode 216] 组合总和 III
- 解法:
- 代码
1 | class Solution { |
6.[Leetcode 131] 分割回文串
解法:
按解组合的方式解,解的过程中判断回文串,组合的元素集合是按照从子串的第一个元素开始,到第i个元素截断作为一个新子串进行回文判断,
代码:
1 | class Solution { |
7.机器人运动范围
规规矩矩没啥说的, 主要注意边界条件
代码:
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
41class Solution {
public:
int movingCount(int threshold, int rows, int cols)
{
int res = 0;
vector<vector<int>> visited (rows, vector<int>(cols, 0));
Dfs(threshold, rows, cols, 0, 0, res, visited);
return res;
}
void Dfs(const int& threshold, const int& rows, const int& cols, int rowIdx, int colIdx, int& res, vector<vector<int>>& visited){
if (JudgeOverThreshold(threshold, rowIdx, colIdx) || JudgeOutside(rows, cols, rowIdx, colIdx) || visited[rowIdx][colIdx] )
return;
visited[rowIdx][colIdx] = 1;
res ++;
Dfs(threshold, rows, cols, rowIdx+1, colIdx, res, visited);
Dfs(threshold, rows, cols, rowIdx, colIdx+1, res, visited);
Dfs(threshold, rows, cols, rowIdx-1, colIdx, res, visited);
Dfs(threshold, rows, cols, rowIdx, colIdx-1, res, visited);
}
bool JudgeOverThreshold(const int& threshold, int rowIdx, int colIdx){
int sum = 0;
while(rowIdx){
sum += rowIdx%10;
rowIdx /= 10;
}
while(colIdx){
sum += colIdx%10;
colIdx /= 10;
}
if(sum > threshold) return true;
else return false;
}
bool JudgeOutside(const int& rows, const int& cols, const int& rowIdx, const int& colIdx){
if(rowIdx < 0 || rowIdx > rows-1 || colIdx < 0 || colIdx > cols-1) return true;
else return false;
}
};