class Solution {
private:
//没有涂
static constexpr int UNCOLORED = 0;
static constexpr int RED = 1;
static constexpr int GREEN = 2;
vector<int> color;
bool valid;
public:
void dfs(int node, int c, const vector<vector<int>>& graph) {
//color数组进行标记
color[node] = c;
//下一个节点涂不一样的颜色
int cNei = (c == RED ? GREEN : RED);
for (int neighbor: graph[node]) {
//没涂颜色 进行递归
if (color[neighbor] == UNCOLORED) {
dfs(neighbor, cNei, graph);
if (!valid) {
return;
}
}
//下一个节点与上一个节点一样颜色则不合格
else if (color[neighbor] != cNei) {
valid = false;
return;
}
}
}
//核心思想为涂色 每一条边的两个节点进行涂色
//第一个节点涂红色
//同一条边的另一个节点涂绿色
bool isBipartite(vector<vector<int>>& graph) {
int n = graph.size();
valid = true;
//初始化0
color.assign(n, UNCOLORED);
for (int i = 0; i < n && valid; ++i) {
//没有涂的。先涂上红色
//先遍历第一层
if (color[i] == UNCOLORED) {
dfs(i, RED, graph);
}
}
return valid;
}
};
class Solution {
private:
static constexpr int dirs[4][2] = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};
public:
vector<vector<int>> updateMatrix(vector<vector<int>>& matrix) {
int m = matrix.size(), n = matrix[0].size();
vector<vector<int>> dist(m, vector<int>(n));
vector<vector<int>> seen(m, vector<int>(n));
queue<pair<int, int>> q;
// 将所有的 0 添加进初始队列中
for (int i = 0; i < m; ++i) {
for (int j = 0; j < n; ++j) {
if (matrix[i][j] == 0) {
q.emplace(i, j);
seen[i][j] = 1;
}
}
}
// 广度优先搜索
while (!q.empty()) {
auto [i, j] = q.front();
q.pop();
for (int d = 0; d < 4; ++d) {
int ni = i + dirs[d][0];
int nj = j + dirs[d][1];
if (ni >= 0 && ni < m && nj >= 0 && nj < n && !seen[ni][nj]) {
dist[ni][nj] = dist[i][j] + 1;
q.emplace(ni, nj);
seen[ni][nj] = 1;
}
}
}
return dist;
}
};
class Solution {
public:
int openLock(vector<string>& deadends, string target) {
if (target == "0000") {
return 0;
}
unordered_set<string> dead(deadends.begin(), deadends.end());
if (dead.count("0000")) {
return -1;
}
auto num_prev = [](char x) -> char {
return (x == '0' ? '9' : x - 1);
};
auto num_succ = [](char x) -> char {
return (x == '9' ? '0' : x + 1);
};
// 枚举 status 通过一次旋转得到的数字
auto get = [&](string& status) -> vector<string> {
vector<string> ret;
for (int i = 0; i < 4; ++i) {
char num = status[i];
status[i] = num_prev(num);
ret.push_back(status);
status[i] = num_succ(num);
ret.push_back(status);
status[i] = num;
}
return ret;
};
queue<pair<string, int>> q;
q.emplace("0000", 0);
unordered_set<string> seen = {"0000"};
while (!q.empty()) {
auto [status, step] = q.front();
q.pop();
for (auto&& next_status: get(status)) {
if (!seen.count(next_status) && !dead.count(next_status)) {
if (next_status == target) {
return step + 1;
}
q.emplace(next_status, step + 1);
seen.insert(move(next_status));
}
}
}
return -1;
}
};