Google Interview Question
InternsInterview Type: Phone Interview
Here is a regular Weighted Digraph. It shouldn't be that hard to modify it so that it solves this problem.
#include <iostream>
#include <vector>
#include <stack>
#include <algorithm>
class WeightedEdge {
public:
WeightedEdge(int a, int b, int weight)
: a_(a), b_(b), weight_(weight)
{}
int either() const {
return a_;
}
int other(int some) const {
if(a_ == some) return b_;
else if(b_ == some) return a_;
else return -1;
}
int weight() const {
return weight_;
}
bool operator==(const WeightedEdge& other) const {
return (a_ == other.a_ && b_ == other.b_ && weight_ == other.weight_)
|| (a_ == other.b_ && b_ == other.a_ && weight_ == other.weight_);
}
bool operator<(const WeightedEdge& other) const {
return weight_ < other.weight_;
}
bool operator>(const WeightedEdge& other) const {
return weight_ > other.weight_;
}
WeightedEdge& operator=(const WeightedEdge& other) {
a_ = other.a_;
b_ = other.b_;
weight_ = other.weight_;
return *this;
}
private:
int a_;
int b_;
int weight_;
};
class EdgeWeightedGraph {
public:
EdgeWeightedGraph(int size)
: adjacency_(size)
{}
void add_edge(int a, int b, int weight) {
if(a < adjacency_.size() && b < adjacency_.size() && std::find(adjacency_[a].begin(), adjacency_[a].end(), WeightedEdge(a, b, weight)) == adjacency_[a].end()) {
adjacency_[a].emplace_back(a, b, weight);
adjacency_[b].emplace_back(a, b, weight);
}
}
const std::vector<WeightedEdge>& adjacent(int a) const {
return adjacency_[a];
}
void print() const {
for(std::size_t i = 0; i < adjacency_.size(); ++i)
for(const auto& e : adjacency_[i])
std::cout << i << " " << e.other(i) << " " << e.weight() << std::endl;
}
std::vector<WeightedEdge> edges() const {
std::vector<WeightedEdge> res;
for(std::size_t i = 0; i < adjacency_.size(); ++i) {
for(const WeightedEdge& e : adjacency_[i])
if(i < e.other(i)) res.push_back(e);
}
return res;
}
std::vector<int> dfs(int start) const {
std::vector<bool> visited(adjacency_.size(), false);
std::stack<int> nodes_stack;
std::vector<int> res;
nodes_stack.push(start);
while(!nodes_stack.empty()) {
int curr = nodes_stack.top();
nodes_stack.pop();
if(!visited[curr]) {
res.push_back(curr);
visited[curr] = true;
for(const auto& e : adjacent(curr)) {
if(!visited[e.other(curr)])
nodes_stack.push(e.other(curr));
}
}
}
return res;
}
std::size_t size() const {
return adjacency_.size();
}
private:
std::vector<std::vector<WeightedEdge>> adjacency_;
};
int main() {
EdgeWeightedGraph graph(6);
graph.add_edge(0, 1, 1);
graph.add_edge(0, 2, 2);
graph.add_edge(0, 5, 3);
graph.add_edge(2, 4, 4);
graph.add_edge(3, 4, 5);
graph.add_edge(3, 5, 6);
graph.add_edge(4, 5, 7);
// graph.print();
// for(int i : graph.dfs(0))
// std::cout << i << std::endl;
for(const WeightedEdge& e : graph.edges())
std::cout << e.either() << " " << e.other(e.either()) << " " << e.weight() << std::endl;
return 0;
}
Assuming that island is represented as a 2d matrix "Isl", Isl[i][j] will denote the height of the cliff at point x,y on the island, given the starting point of the droplet, we can do a bfs, visiting valid neighbours of less or equal heights, storing the visited point i,j in a seperate matrix. Finally find the minimum height amongst the visited vertices will give answer.
Its simple to implement, just normal bfs
Assuming that there cannot be two neighboring cliffs of the same height, as those shall be treated as the same cliff.
- losmi April 17, 2017Model the island as a directed graph where each cliff is a node with edges pointing to neighboring cliffs of lower height. Now use DFS from the starting cliff to find all cliffs which are surrounded only by higher cliffs. Remember which cliffs you have already visited in order to save checking the same path after some "fork-merge". After each fork determine which path went to the lower cliff. At the end return the lowest cliff.