Algorithm - Colour surrounded by another colour in a matrix - algorithm

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).

Related

Edmond matching algorithm. How to start with a empty matching set?

I would like to perform the Edmond matching algorithm or Blossom algorithm on a Graph (example Graph in picture), but how to I start with a empty matching set?
The Algorithm work this way:
Given: Graph G and matching M in G
Task: find matching M' with |M'| =
[M| + 1, or |M'| = IM| if M maximum
1 let F be the forest consisting of all M-exposed nodes; 2 while there
is outer node x and edge {x, y) with y \in V(F), add (x, y} and
matching edge covering y to F;
3 if there are adjacent outer nodes x, y in same tree, then shrink
cycle (M-blossom) in F \cup {x, y) and go to Step 2;
4 if there are adjacent outer nodes x, y in different trees, then
augment M along M-augmenting path P(x) \cup {x, y} \cup P(y);
5 in reverse order, undo each shrinking and re-establish near-perfect
matchings in blossoms.
You don’t begin the algorithm with an empty M. You have to provide one, generally by generating it with a greedy algorithm that parses all edges e of the graph G and adds each e to M if M + e form a matching.

Converting from triangle strip to polygon

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.

Find the simple path with at least 5 edges in directed graph

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.

Interview Prep Words in a Grid

I've been doing interview prep questions and this is a question that I've had trouble with as I'm unsure how to implement the solution. So here's the setup. You're given an 8x8 grid of letters and a list of words, and you must return the longest word in the list that can be formed by starting at a letter on the grid and then moving about the grid in the way that a knight would in chess. For example, if you had the list ["word", "string", "test"] and the following grid:
Y W E Z T N U W
O P A A C Q G F
T E L Z X C V B
N M M W F R T O
U I O N A S D F
B E J O L Z V C
T B N M Q W E R
T A S G X Z R S
Then you would return "test", because this can be formed by starting at the bottom left corner of the grid for 'T', jumping up two and to the right one to get the 'E', jumping down two and right one to get the 'S', and then left two and up one to get the 'T', and none of the other words can be formed on this grid.
I think you'd use a branch and bound algorithm but I'm totally lost on how to set that up. Could anyone help? I'm trying to implement in python.
Note: letters can be repeated in the grid, i.e. you can jump on the same letter as many times as you want.
My solution is:
for every word in the array, iterate through the matrix to find the first letter then you can use a breath first search (BFS) or a depth first search (DFS) on the first letter's neighbors( in this case it would be the 8 positions a knight can jump to) to see if they match up. you can implement BFS or DFS iteratively using a queue or stack respectively.

Finding optimal algorithm for constructing biggest square from colored tiles

I've got N square tiles. Each side of tile is colored in red, green or blue color. The goal is to form biggest possible square from tiles in such a way that adjacent edges are of same color.
Example 1: let N,W,S,E represent north, west, south and east tile side respectivly, and R,G,B represent colors. We got 5 tiles
N W S E
1 B R B R 1 4
2 B G R B i can form 2x2 square from it placing tiles like this 2 3
3 B G G G
4 G R B R
5 G R B R
Example 2: We got 6 tiles
N W S E
1 B B B B
2 B B B B
3 G G G G
4 G G G G
5 G G G G
6 R R R R
Biggest possible square to build here is 1x1.
I will be developing application solving this task. What would be good algorithm to find the best solution in shortest time?
You can obviously find a solution by writing down a set of constraints on the tiles chosen to fit each location and then using backtracking search. I will be surprised if there is a better general solution, because it appears that you can encode very general problems as tiling problems - see http://en.wikipedia.org/wiki/Wang_tile

Resources