- 79. 单词搜索 中等
- 85. 最大矩形 困难
- 200. 岛屿数量 中等
- 207. 课程表 中等
- 301. 删除无效的括号 困难


class Solution {
public:
bool exist(vector<vector<char>>& board, string word) {
rows = board.size();
cols = board[0].size();
for(int i = 0; i < rows; i++) {
for(int j = 0; j < cols; j++) {
if (dfs(board, word, i, j, 0)) return true;
}
}
return false;
}
private:
int rows, cols;
bool dfs(vector<vector<char>>& board, string word, int i, int j, int k) {
if (i >= rows || i < 0 || j >= cols || j < 0 || board[i][j] != word[k]) return false;
if (k == word.size() - 1) return true;
board[i][j] = '\0';
bool res = dfs(board, word, i + 1, j, k + 1) || dfs(board, word, i - 1, j, k + 1) ||
dfs(board, word, i, j + 1, k + 1) || dfs(board, word, i , j - 1, k + 1);
board[i][j] = word[k];
return res;
}
};



- 遍历整个矩阵,当遇到
grid[i][j] == '1' 时,从此点开始做深度优先搜索 dfs,岛屿数 count + 1 且在深度优先搜索中删除此岛屿
- 设目前指针指向一个岛屿中的某一点
(i, j),寻找包括此点的岛屿边界
- 从
(i, j) 向此点的上下左右 (i+1,j),(i-1,j),(i,j+1),(i,j-1) 做深度搜索
- 终止条件: 1:
(i, j) 越过矩阵边界; 2: grid[i][j] == 0,代表此分支已越过岛屿边界
- 搜索岛屿的同时,执行
grid[i][j] = '0',即将岛屿所有节点删除,以免之后重复搜索相同岛屿。
class Solution {
public:
int numIslands(vector<vector<char>>& nums) {
int res = 0;
int m = nums.size(),
n = nums[0].size();
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
if (nums[i][j] == '1') {
dfs(nums, i, j);
res ++;
}
}
}
return res;
}
void dfs(vector<vector<char>>& nums, int i, int j) {
if (i < 0 || j < 0 || i >= nums.size() || j >= nums[0].size() || nums[i][j] == '0')
return;
nums[i][j] = '0'
dfs(nums, i + 1, j);
dfs(nums, i, j + 1);
dfs(nums, i - 1, j);
dfs(nums, i, j - 1);
}
};
- 时间复杂度:O(MN),其中 M 和 N 分别为行数和列数
- 空间复杂度:O(MN),在最坏情况下,整个网格均为陆地,深度优先搜索的深度达到 MN

解法1: bfs版本

- 维护入度表, 邻接表以及队列
- 队列存放入度为0的节点
class Solution {
public:
bool canFinish(int numCourses, vector<vector<int>>& prerequisites) {
vector<int> indegrees(numCourses, 0);
vector<vector<int>> adjacency(numCourses);
queue<int> q;
for (auto &vec : prerequisites) {
indegrees[vec[0]]++;
adjacency[vec[1]].push_back(vec[0]);
}
for (int i = 0; i < numCourses; ++i) {
if (indegrees[i] == 0) {
q.push(i);
}
}
while (!q.empty()) {
int pre = q.front(); q.pop();
numCourses--;
for (auto near : adjacency[pre]) {
if (--indegrees[near] == 0) q.push(near);
}
}
return numCourses == 0;
}
};
解法1: 深度优先遍历

class Solution {
public:
bool canFinish(int numCourses, vector<vector<int>>& prerequisites) {
vector<vector<int> > adjacent(numCourses);
vector<int> flags(numCourses);
for(int i=0; i<prerequisites.size(); i++){
adjacent[prerequisites[i][0]].push_back(prerequisites[i][1]);
}
for(int i=0; i<numCourses; i++){
if(!DFS(i, adjacent, flags)) return false;
}
return true;
}
bool DFS(int i, vector<vector<int> > &adjacent, vector<int> &flags){
if(flags[i]==-1) return true;
if(flags[i]==1) return false;
flags[i]=1;
for(auto j:adjacent[i]){
if(!DFS(j, adjacent, flags)) return false;
}
flags[i]=-1;
return true;
}
};

解法一:回溯 + 剪枝

class Solution {
public:
vector<string> res
vector<string> removeInvalidParentheses(string s) {
int lremove = 0
int rremove = 0
for (char c : s) {
if (c == '(') {
lremove++
} else if (c == ')') {
if (lremove == 0) {
rremove++
} else {
lremove--
}
}
}
helper(s, 0, lremove, rremove)
return res
}
void helper(string str, int start, int lremove, int rremove) {
if (lremove == 0 && rremove == 0) {
if (isValid(str)) {
res.push_back(str)
}
return
}
for (int i = start
if (i != start && str[i] == str[i - 1]) {
continue
}
// 如果剩余的字符无法满足去掉的数量要求,直接返回
if (lremove + rremove > str.size() - i) {
return
}
// 尝试去掉一个左括号
if (lremove > 0 && str[i] == '(') {
helper(str.substr(0, i) + str.substr(i + 1), i, lremove - 1, rremove)
}
// 尝试去掉一个右括号
if (rremove > 0 && str[i] == ')') {
helper(str.substr(0, i) + str.substr(i + 1), i, lremove, rremove - 1)
}
}
}
inline bool isValid(const string & str) {
int cnt = 0
for (int i = 0
if (str[i] == '(') {
cnt++
} else if (str[i] == ')') {
cnt--
if (cnt < 0) {
return false
}
}
}
return cnt == 0
}
}

解法二: 广度优先搜索
class Solution {
public:
bool isValid(string str) {
int count = 0
for (char c : str) {
if (c == '(') {
count++
} else if (c == ')') {
count--
if (count < 0) {
return false
}
}
}
return count == 0
}
vector<string> removeInvalidParentheses(string s) {
vector<string> ans
unordered_set<string> currSet
currSet.insert(s)
while (true) {
for (auto & str : currSet) {
if (isValid(str))
ans.emplace_back(str)
}
if (ans.size() > 0) {
return ans
}
unordered_set<string> nextSet
for (auto & str : currSet) {
for (int i = 0
if (i > 0 && str[i] == str[i - 1]) {
continue
}
if (str[i] == '(' || str[i] == ')') {
nextSet.insert(str.substr(0, i) + str.substr(i + 1, str.size()))
}
}
}
currSet = nextSet
}
}
}
