Search Space: Interview Problem Survey
classic binary search is used to solve many problems like leetcode 35. Where we would like to find the position we insert a given value into an already sorted list. Example instance; [1,3,5,6], 5 Example solution; 2 Example code; function searchInsert(vector list, int to_insert) { int pivot, left = 0; right = list.length()-1; while(left > 2; if(list[pivot] == to_insert) { return pivot; } if(to_insert > list[pivot]) { left = pivot + 1; } else { right = pivot - 1; } } } Similar to depth-first search or breadth-first search. This algorithm can be used as a sub-routine when search in a space if the space is already structured. Lets look at leetcode 778 Where we are given a slowly filling pool and must swim from one end of the pool to the next. Where we use binary search to guess our constraint; time. Then perform traditional depth-first search to reach the end. Example instance; [[0,2],[1,3]] Example solution; 3 Example code; class Solution { private: bool possible(int time, vector grid, int i, int j) { int RN = grid.size(); int CN = grid.at(0).size(); if(i == RN-1 && j == CN-1) return true; if(i + 1 < RN && grid.at(i+1).at(j) < time) { return possible(time, grid, i+1, j); } if(i - 1 >= 0 && grid.at(i-1).at(j) < time) { return possible(time, grid, i-1, j); } if(j + 1 < CN && grid.at(i).at(j+1) < time) { return possible(time, grid, i, j+1); } if(j - 1 >= 0 && grid.at(i).at(j-1) < time) { return possible(time, grid, i, j-1); } return false; } public: int swimInWater(vector grid) { int L = 1, H = grid.size() * grid.at(0).size(); while(start < max_time) { int M = (L+H) >> 1; if(!possible(M, grid, 0, 0)) { L = M+1; } else { H = M-1; } } } } This problem can also be solved with Dijkstra's algorithm and Union-Find. The intuition behind Dijkstra's being to first identify Optimal Sub-structure Example Dijkstra's; struct V { int v, x, y V(int v_, int x_, int y_) : v(v_), x(x_), y(y_) {} bool operator< (const V &c) const { return this.v > c.v; } } class Solution { private: priority_queue pq; int M; int N; public: int swimInWater(vector grid) { M = grid.size(); N = grid.at(0).size(); pq.push(V(grid[0][0], 0,0)); vector seen(M, vector(N); seen[0][0] = true; while(!pq.empty()) { V p = pq.top(); pq.pop(); res = max(res, p.v); if(p.x == M - 1 && p.y == N - 1) { return res; } if(p.x + 1 < M && !seen[p.x+1][p.y]) { seen[p.x+1][p.y] = true; pq.push(V(grid[p.x+1][p.y], p.x, p.y); } if(p.x - 1 < M && !seen[p.x-1][p.y]) { seen[p.x-1][p.y] = true; pq.push(V(grid[p.x-1][p.y], p.x, p.y); } if(p.y + 1 < M && !seen[p.x][p.y+1]) { seen[p.x][p.y+1] = true; pq.push(V(grid[p.x][p.y+1], p.x, p.y); } if(p.y - 1 < M && !seen[p.x][p.y-1]) { seen[p.x][p.y-1] = true; pq.push(V(grid[p.x][p.y-1], p.x, p.y); } } } } This differences between this question and network delay where we already used Dijsktra's is that we only care about reaching the end node, so instead of keep track of the largest ingress to the node we check if we have seen the node before. Another method being union-find, which more directly answers the question is the groups which connect the start to end node.

classic binary search is used to solve many problems like leetcode 35. Where we would like to find the position we insert a given value into an already sorted list.
Example instance;
[1,3,5,6], 5
Example solution;
2
Example code;
function searchInsert(vector list, int to_insert) {
int pivot, left = 0; right = list.length()-1;
while(left <= right) {
pivot = (left+right) >> 2;
if(list[pivot] == to_insert) {
return pivot;
}
if(to_insert > list[pivot]) {
left = pivot + 1;
} else {
right = pivot - 1;
}
}
}
Similar to depth-first search or breadth-first search. This algorithm can be used as a sub-routine when search in a space if the space is already structured.
Lets look at leetcode 778 Where we are given a slowly filling pool and must swim from one end of the pool to the next. Where we use binary search to guess our constraint; time. Then perform traditional depth-first search to reach the end.
Example instance;
[[0,2],[1,3]]
Example solution;
3
Example code;
class Solution {
private:
bool possible(int time, vector> grid, int i, int j)
{
int RN = grid.size();
int CN = grid.at(0).size();
if(i == RN-1 && j == CN-1) return true;
if(i + 1 < RN && grid.at(i+1).at(j) < time) {
return possible(time, grid, i+1, j);
}
if(i - 1 >= 0 && grid.at(i-1).at(j) < time) {
return possible(time, grid, i-1, j);
}
if(j + 1 < CN && grid.at(i).at(j+1) < time) {
return possible(time, grid, i, j+1);
}
if(j - 1 >= 0 && grid.at(i).at(j-1) < time) {
return possible(time, grid, i, j-1);
}
return false;
}
public:
int swimInWater(vector> grid) {
int L = 1, H = grid.size() * grid.at(0).size();
while(start < max_time) {
int M = (L+H) >> 1;
if(!possible(M, grid, 0, 0)) {
L = M+1;
} else {
H = M-1;
}
}
}
}
This problem can also be solved with Dijkstra's algorithm and Union-Find. The intuition behind Dijkstra's being to first identify Optimal Sub-structure
Example Dijkstra's;
struct V {
int v, x, y
V(int v_, int x_, int y_) : v(v_), x(x_), y(y_) {}
bool operator< (const V &c) const { return this.v > c.v; }
}
class Solution {
private:
priority_queue pq;
int M;
int N;
public:
int swimInWater(vector> grid) {
M = grid.size();
N = grid.at(0).size();
pq.push(V(grid[0][0], 0,0));
vector> seen(M, vector(N);
seen[0][0] = true;
while(!pq.empty()) {
V p = pq.top();
pq.pop();
res = max(res, p.v);
if(p.x == M - 1 && p.y == N - 1) {
return res;
}
if(p.x + 1 < M && !seen[p.x+1][p.y]) {
seen[p.x+1][p.y] = true;
pq.push(V(grid[p.x+1][p.y], p.x, p.y);
}
if(p.x - 1 < M && !seen[p.x-1][p.y]) {
seen[p.x-1][p.y] = true;
pq.push(V(grid[p.x-1][p.y], p.x, p.y);
}
if(p.y + 1 < M && !seen[p.x][p.y+1]) {
seen[p.x][p.y+1] = true;
pq.push(V(grid[p.x][p.y+1], p.x, p.y);
}
if(p.y - 1 < M && !seen[p.x][p.y-1]) {
seen[p.x][p.y-1] = true;
pq.push(V(grid[p.x][p.y-1], p.x, p.y);
}
}
}
}
This differences between this question and network delay where we already used Dijsktra's is that we only care about reaching the end node, so instead of keep track of the largest ingress to the node we check if we have seen the node before.
Another method being union-find, which more directly answers the question is the groups which connect the start to end node.