I recently faced this problem in an interview:
Given below matrix:
[[ R R R R R R],
[ R B B B R R],
[ B R R R B B],
[ R B R R R R]]
Find out if any group of only R's or only B's surrounded by Opposite colour in the 4 directions: up, down, left, right corners.
ex: Answer for the above matrix -> Valid set of B's surrounded by R's in the second row.
[[ R R R R R R],
[ R **B B B** R R],
[ B R R R B B],
[ R B R R R R]]
I tried doing a BFS for a specific colour in all directions but was unable to come up to solution.
Can someone guide me to the solution.
To find the groups of B cells surrounded by R cells, think of the matrix as a graph whose vertices are all the B cells, with edges connecting adjacent B cells. Use BFS (or DFS) to find the connected components of this graph, but ignore the connected components that contain cells on the boundary. Each (non-boundary) connected component contains a set of B cells surrounded by R cells. Then, to find the groups of R cells surrounded by B cells, similarly compute the non-boundary connected components of the graph whose vertices are the R cells.
Since the number of vertices and edges of both graphs is O(mn) and the set of connected components of a graph can be found in time that is linear in the graph's size, the running time of this algorithm is O(mn).
I've some areas which contains 1 or more polygons. Each polygon is represented in GL_TRIANGLE_STRIP format, where each vertex is a pair of (lat, long). Is there any way to get the contours of the area?
Some specs:
Contours must be in counter clockwise order.
Any 2 polygons can have one common edge.
Polygons can be concave
A polygon can have maximum 1 'gap' inside of it, which will be represented by another contour, in clockwise order.
I'm looking for an algorithm which complexity is around O(N*logN), where N = number of vertices.
EDIT: I tried solutions like going 2 by 2 until I reach the end of the dataset and then going backwards, but this algorithm works bad on polygons with gaps, for example
this polygon where input is: A B C D E F G H I J, where I = A and J = B, doing that, the output will be A C E G I J H F D B and that should be A C E G and B H F G (order is inverted because it was easier to draw like that).
Another solution was considering points an undirected graph and edges between them (according to GL_TRIANGLE_STRIP format) where I applied a DFS in order to take out connected components. After that I computed the area of each component, and I considered the maximum area polygon as the counter clockwise contour, and the rest as the clockwise contour. That doesn't work because adjacency list requires some sorting which will make the algorithm inefficient.
Another solution I tried was some tweaked convex hull, but a convex hull is still a convex hull and did not work on concave polygons.
I also read about concave hull, but that seems to not give always precise results.
Thank you for your answers!
Let's start by converting a triangle strip to a polygon. We take the following strip as an example:
(Courtesy of Wikimedia Commons)
Your strip definition would be:
A B C D E F
Converting that into a polygon is very simple. Just go through the list and use every second vertex. When you are at the end, return backwards and use the other vertices. In this case:
A C E (reached the end, now return) F D B
This can be done in O(N), where N is the number of vertices of the strip. Whether this is clockwise or counter-clockwise depends on the orientation of the strip.
So, we can turn every strip into a polygon. All that remains is to remove shared edges. Let's say we have two polygons
A C E F D B
W X E C Y Z
Note that any edge that is shared (in this case C E) will appear in opposite directions (C E in the first polygon, E C in the second one). To find the area contour, we simply need to find matching edges and merge the two polygons.
To find matching edges, it is enough to write all the polygon edges into a hash map (store what polygon they belong to and where they are in the polygon). This can be done in O(E), where E is the total number of polygon edges.
To finally merge polygons, it is actually simpler to create new ones. Modification is definitely possible, but a bit more delicate. To do that we just need to walk along our polygon edges. As long as we are on an edge whose inverse is not in the hash map, then write this edge to the output polygon. If it is, ignore it and continue on the other polygon. Mark the edges that you visited and stop as soon as you are back to an edge that you visited before. Do this until all edges are visited (or both directions are in the hash map). This whole process can be done in O(E), where E is the total number of polygon edges.
Here is how that would look like in our example:
Start at polygon 1
Start at edge (A, C)
(A, C) is neither visited nor is its inverse in the hash map
Create new output area = [A, C]
the inverse of (C, E) is in the hash map, continue to polygon 2
(C, Y) is neither visited nor is its inverse in the hash map
Append it to the area = [A, C, Y]
(Y, Z) is neither visited nor is its inverse in the hash map
Append it to the area = [A, C, Y, Z]
(Z, W) is neither visited nor is its inverse in the hash map
Append it to the area = [A, C, Y, Z, W]
(W, X) is neither visited nor is its inverse in the hash map
Append it to the area = [A, C, Y, Z, W, X]
(X, E) is neither visited nor is its inverse in the hash map
Append it to the area = [A, C, Y, Z, W, X, E]
the inverse of (E, C) is in the hash map, continue to polygon 1
(E, F) is neither visited nor is its inverse in the hash map
Append it to the area = [A, C, Y, Z, W, X, E, F]
(F, D) is neither visited nor is its inverse in the hash map
Append it to the area = [A, C, Y, Z, W, X, E, F, D]
(D, B) is neither visited nor is its inverse in the hash map
Append it to the area = [A, C, Y, Z, W, X, E, F, D, B]
(B, A) is neither visited nor is its inverse in the hash map
Append it to the area = [A, C, Y, Z, W, X, E, F, D, B, A]
(A, C) is already visited
Close the area contour, continue to check other unvisited edges
If you want, you can then also group the generated contours by the polygons they were created from to find connected areas that are bounded by multiple contours. A disjoint set over the polygons would be helpful for that task. If you need, you could also try to classify the contours into holes and outer contours. But be aware that this notion is highly ambiguous on the sphere (imagine a sphere and an area that is a band along the equator - which of the two contours is the hole and which is outside?) For comparatively small areas, you could use the area for this classification.
I have a question.
Given a directed graph (G = V, E) and the source vertex s from V group.
we want to check whether there is a simple path (no circles) from s to any vertex in G with at least 5 edges.
Offer as efficient an algorithm as possible that solves the problem for a graph G that can contain circles.
please I need your help
Thanks :-)
We need to find any 5-edge simple directed path starting at vertex s. This path will look like:
s -> a -> b -> c -> d -> e (all distinct)
Now let's go through the all possible values of c (any vertex besides s) and then for every c value we can go through all edges that do not contain s and c vertices and for the edge (x, y) do the following:
if edge (s, x) exists and edge (y, c) exists
put (x, y) in AB edges list
if edge (c, x) exists
put (x, y) in DE edges list
This can be done in O(|E|). Then we need to find a pair of edges (E1, E2) such that E1 is in AB, E2 is in DE and they don't share any vertex in common. The latter can be done in O(|E|).
We can take a graph G' = (V, DE) and find the degrees of the vertices. Then for every edge (a, b) from AB we need to check that
degree(a) + degree(b) = |DE| + x
where x = 1 if (a, b) is in DE, otherwise x = 0. If this equality does not hold it means that there is an edge in DE that contains neither a nor b and we can just iterate through entire DE to find the answer.
The overall complexity will be O(|V||E|) with O(|E|) additional memory.
Given an undirected graph G with edge weights, a set of candidate edges (length |V| + |E|), and vertices A and B, find the edge that decreases the shortest path from A to B by the most.
For example:
The candidate edges are the dotted lines. The shortest path from A to B is A -> C -> D -> G -> B (cost 7). But with the edge (D, B), the shortest path is A -> C -> D -> B (cost 6), so the algorithm should return (D, B).
I came up with a brute force solution O((|V| + |E|)^2 log |V|):
for each candidate edge:
add the edge to the graph
run Dijkstra's to find the cost of the shortest path from A to B
remove the edge
return the candidate edge that results in the shortest path
but is there anything better?
One approach is:
Run Dijkstra from A and store distance to each node n in A[n]
Run Dijkstra from B and store distance to each node n in B[n]
Loop over each candidate edge. For an edge with weight w that connects vertices x and y, compare w+A[x]+B[y] and w+A[y]+B[x]
The smaller of w+A[x]+B[y] and w+A[y]+B[x] gives the shortest path between A and B when the candidate edge is used.
I want to find the weight of the edges of a graph by using the output of the Prim's algorithm.
Note: In a graph has n edges, each edge is different and between 1-n.
For example:
Vertices = {A, B, C, D, E}
Edges = {B-D, D-E, E-A, C-B, A-D, D-C, A-C}
Extract_Min() Order = B D C A E
By using the information above, I want to find the weight of each edge. Do you have any ideas?
Thanks in advance.
Edit: The solution does not have to be unique.
By your example:
Vertices = {A, B, C, D, E}
Edges = {B-D, D-E, E-A, C-B, A-D, D-C, A-C}
Extract_Min() Order = B D C A E
Look at the order given by Extract_Min().
The edge with weight 1 is surely B-D.
Assign weight 2 to some single edge from the set {B,D} to C.
Assign weight 3 to some single edge from the set {B,D,C} to A.
Assign weight 4 to some single edge from the set {B,D,C,A} to E.
Assign the remaining weights to the remaining edges in any order.