Commit 17894f13 authored by anqiwa's avatar anqiwa 😲
Browse files

update 8/19/21

parent 79e7474f
/*
* @lc app=leetcode id=1036 lang=cpp
*
* [1036] Escape a Large Maze
*/
// @lc code=start
using PII = pair<int, int>;
class Solution
{
double n = 1e6;
int MAX_ENCLOSE = 19900; // 200格子斜着围角
vector<pair<int, int>> dirs = {
{1, 0}, {0, 1}, {-1, 0}, {0, -1}};
enum class Status
{
MEET, // begin meet end
ENCLOSED, // begin is enclosed
NENCLOSED // begin is not enclosed
};
public:
bool isEscapePossible(vector<vector<int>> &blocked,
vector<int> &source,
vector<int> &target)
{
PII src = {source[0], source[1]};
PII tar = {target[0], target[1]};
set<pair<int, int>> blocks;
for (auto &b : blocked)
blocks.insert({b[0], b[1]});
auto fromSrc = bfs(blocks, src, tar);
if (fromSrc == Status::MEET)
return true;
else if (fromSrc == Status::ENCLOSED)
return false;
auto fromTar = bfs(blocks, tar, src);
return fromTar != Status::ENCLOSED;
}
Status bfs(set<pair<int, int>> &blocks,
PII &begin,
PII &end)
{
queue<PII> q;
set<PII> visited;
q.push(begin);
visited.insert(begin);
while (!q.empty())
{
if (visited.size() > MAX_ENCLOSE)
return Status::NENCLOSED;
auto [curr_x, curr_y] = q.front();
q.pop();
for (auto &dir : dirs)
{
int n_x = curr_x + dir.first;
int n_y = curr_y + dir.second;
if (n_x == end.first && n_y == end.second)
return Status::MEET;
if (n_x < 0 || n_y < 0 || n_x >= n || n_y >= n)
continue;
if (blocks.find({n_x, n_y}) != blocks.end())
continue;
if (visited.find({n_x, n_y}) != visited.end())
continue;
q.push({n_x, n_y});
visited.insert({n_x, n_y});
} //for
} //while
return Status::ENCLOSED;
}
};
// @lc code=end
class Solution
{
vector<vector<int>> graph;
int n; // num of nodes
public:
int treeDiameter(vector<vector<int>> &edges)
{
// randomly pick a node A
// use bfs to find the longest node B from A
// than find the longest path C from B
// BC is the diameter of the given tree
//1. construct an adjacency matrix
n = edges.size() + 1;
graph.resize(n);
for (auto edge : edges)
{
int a = edge[0];
int b = edge[1];
graph[a].push_back(b);
graph[b].push_back(a);
} //for
int A = 0;
auto [B, AB] = bfs(A);
auto [C, BC] = bfs(B);
return BC;
}
// use bfs to return the furthest node from the given node u
pair<int, int> bfs(int u)
{
vector<int> dis(n, -1);
queue<int> q;
q.push(u);
dis[u] = 0;
while (!q.empty())
{
int t = q.front();
q.pop();
for (auto it = graph[t].begin(); it != graph[t].end(); it++)
{
int v = *it;
if (dis[v] == -1)
{
q.push(v);
dis[v] = dis[t] + 1;
}
}
}
auto maxPath = max_element(dis.begin(), dis.end());
int maxDis = *maxPath;
int nodeIdx = maxPath - dis.begin();
return make_pair(nodeIdx, maxDis);
}
};
\ No newline at end of file
/*
* @lc app=leetcode id=130 lang=cpp
*
* [130] Surrounded Regions
*/
// @lc code=start
class Solution
{
vector<pair<int, int>> dirs = {{0, 1}, {1, 0}, {0, -1}, {-1, 0}};
public:
void solve(vector<vector<char>> &board)
{
// reverse logic:
// instead to find the Os that are surrounded
// we try to find the Os that are not surrounded
// but start bfs from the border
// use a temp char to locate those and later change them back to O
const int m = board.size();
if (m == 0)
return;
const int n = board[0].size();
// bfs for left most col and right most col
for (int i = 0; i < m; ++i)
{
if (board[i][0] == 'O')
bfs(board, i, 0);
if (board[i][n - 1] == 'O')
bfs(board, i, n - 1);
}
// do for the upper and lower border
for (int j = 0; j < n; ++j)
{
if (board[0][j] == 'O')
bfs(board, 0, j);
if (board[m - 1][j] == 'O')
bfs(board, m - 1, j);
}
for (int i = 0; i < m; ++i)
{
for (int j = 0; j < n; ++j)
{
if (board[i][j] == '$')
board[i][j] = 'O';
else if (board[i][j] == 'O')
board[i][j] = 'X';
}
}
}
void bfs(vector<vector<char>> &board, int x, int y)
{
const int m = board.size();
const int n = board[0].size();
// bfs from the given pt
queue<pair<int, int>> q;
q.push({x, y});
board[x][y] = '$'; // the temp char
while (!q.empty())
{
auto [curr_x, curr_y] = q.front();
q.pop();
// try out 4 direction
for (auto &dir : dirs)
{
int d_x = dir.first;
int d_y = dir.second;
int next_x = curr_x + d_x;
int next_y = curr_y + d_y;
if (next_x < 0 || next_x >= m || next_y < 0 || next_y >= n)
continue;
if (board[next_x][next_y] != 'O')
continue;
board[next_x][next_y] = '$';
q.push({next_x, next_y});
}
} //while
}
};
// @lc code=end
/*
* @lc app=leetcode id=1345 lang=cpp
*
* [1345] Jump Game IV
*/
// @lc code=start
class Solution
{
public:
int minJumps(vector<int> &arr)
{
const int n = arr.size();
if (n == 1)
return 0;
// greedy: we want to visit greater idx first
unordered_map<int, priority_queue<int, vector<int>, less<>>> map;
for (int i = 0; i < arr.size(); ++i)
map[arr[i]].push(i);
vector<bool> visited(n, false);
queue<int> q;
q.push(0);
visited[0] = true;
int step = 0;
while (!q.empty())
{
step++;
int len = q.size();
for (int k = 0; k < len; ++k)
{
auto curr = q.front();
q.pop();
if (curr + 1 < n && !visited[curr + 1])
{
if (curr + 1 == n - 1)
return step;
q.push(curr + 1);
visited[curr + 1] = true;
}
if (curr - 1 >= 0 && !visited[curr - 1])
{
if (curr - 1 == n - 1)
return step;
q.push(curr - 1);
visited[curr - 1] = true;
}
while (!map[arr[curr]].empty())
{
int i = map[arr[curr]].top();
map[arr[curr]].pop();
if (!visited[i])
{
if (i == n - 1)
return step;
q.push(i);
visited[i] = true;
}
} //for
}
} //while
return -1;
}
};
// @lc code=end
class Solution
{
public:
string alienOrder(vector<string> &words)
{
// this is problem is topSort
// step1. make the graph (adjacency list)
unordered_map<char, set<char>> graph;
unordered_map<char, int> inDeg;
for (int i = 0; i < words.size(); i++)
for (int j = 0; j < words[i].size(); j++)
inDeg[words[i][j]] = 0;
string res = "";
// compare each adj words
for (int i = 0; i < words.size() - 1; ++i)
{
string s = words[i];
string t = words[i + 1];
// if s in t and s is longer than t
if (s.size() > t.size() && s.substr(0, t.size()) == t)
return res;
int len = min(s.size(), t.size());
for (int j = 0; j < len; ++j)
{
if (s[j] == t[j])
continue;
if (graph[s[j]].find(t[j]) == graph[s[j]].end())
{
inDeg[t[j]]++;
graph[s[j]].insert(t[j]);
}
break;
} //for
} //for
// do topSort
queue<char> q;
for (auto &p : inDeg)
{
if (p.second == 0)
q.push(p.first);
}
while (!q.empty())
{
char curr = q.front();
q.pop();
res.push_back(curr);
//cout << curr << endl;
for (auto next : graph[curr])
{
inDeg[next]--;
if (inDeg[next] == 0)
q.push(next);
}
} //while
if (res.size() == inDeg.size())
return res;
return "";
}
};
\ No newline at end of file
/*
* @lc app=leetcode id=529 lang=cpp
*
* [529] Minesweeper
*/
// @lc code=start
class Solution
{
vector<pair<int, int>> dirs = {{0, 1},
{1, 0},
{1, 1},
{-1, 0},
{0, -1},
{-1, -1},
{1, -1},
{-1, 1}};
public:
vector<vector<char>>
updateBoard(vector<vector<char>> &board,
vector<int> &click)
{
int c_x = click[0];
int c_y = click[1];
if (board[c_x][c_y] == 'M')
{
board[c_x][c_y] = 'X';
}
else if (board[c_x][c_y] == 'E')
{
bfs(board, c_x, c_y);
}
return board;
}
void bfs(vector<vector<char>> &board, int x, int y)
{
const int m = board.size();
const int n = board[0].size();
vector<vector<bool>> visited(m, vector<bool>(n, false));
queue<pair<int, int>> q;
q.push({x, y});
visited[x][y] = true;
while (!q.empty())
{
auto [curr_x, curr_y] = q.front();
q.pop();
int count = 0;
vector<pair<int, int>> temp;
for (auto &dir : dirs)
{
int n_x = curr_x + dir.first;
int n_y = curr_y + dir.second;
if (n_x < 0 || n_x >= m || n_y < 0 || n_y >= n)
continue;
if (board[n_x][n_y] == 'M')
{
count++;
}
else if (!visited[n_x][n_y])
{
temp.push_back({n_x, n_y});
}
}
if (count != 0)
board[curr_x][curr_y] = count + '0';
else
{
board[curr_x][curr_y] = 'B';
for (auto &p : temp)
{
visited[p.first][p.second] = true;
q.push({p.first, p.second});
}
}
} //while
}
};
// @lc code=end
/*
* @lc app=leetcode id=637 lang=cpp
*
* [637] Average of Levels in Binary Tree
*/
// @lc code=start
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution
{
public:
vector<double> averageOfLevels(TreeNode *root)
{
// level order traversal
queue<TreeNode *> q;
vector<double> res;
q.push(root);
while (!q.empty())
{
int len = q.size();
double sum = 0.0;
for (int i = 0; i < len; ++i)
{
sum += (double)q.front()->val;
if (q.front()->left)
q.push(q.front()->left);
if (q.front()->right)
q.push(q.front()->right);
q.pop();
} //for
res.push_back(sum / (double)len);
} //while
return res;
}
};
// @lc code=end
/*
* @lc app=leetcode id=785 lang=cpp
*
* [785] Is Graph Bipartite?
*/
// @lc code=start
class Solution
{
public:
bool isBipartite(vector<vector<int>> &graph)
{
// for each node in the graph
// if it is not visited
// start from that node
// and do bfs
const int n = graph.size();
vector<int> visited(n, -1);
for (int i = 0; i < n; ++i)
{
if (visited[i] == -1)
if (!bfs(graph, visited, i))
return false;
} //for
return true;
}
// bfs start from the node i
bool bfs(vector<vector<int>> &graph,
vector<int> &visited,
int i)
{
queue<pair<int, int>> q;
q.push({i, 0}); // {node, group}
visited[i] = 0;
while (!q.empty())
{
int node = q.front().first;
int group = q.front().second;
q.pop();
for (auto next : graph[node])
{
if (visited[next] != -1)
{
if (visited[next] != 1 - group)
return false;
}
else
{
visited[next] = 1 - group;
q.push({next, 1 - group});
}
}
}
return true;
}
};
// @lc code=end
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment