I came across to problem on thinking how to get the shape from the rows of characters, for example given this input:
AAAAAAAA
ABBBAABA
ABABABBB
ABBBAAAA
AAAABBAA
ABBABBAA
ABBABBAA
ABAABBAA
Task:
Calculate how many shapes are there formed by horizontally or vertically adjacent 'B' letters.
In this example there are 4 such shapes.
It might be easier to see if I remove the 'A's:
BBB B
B B BBB
BBB
BB
BB BB
BB BB
B BB
Additional task:
How many 'B' characters are in each shape?
In this example: 8, 4, 5, 8 (not in any particular order).
I am still new to Java, so I want to ask is there is any java function that can check the same occurrence that near to each other in order to count the shape appears? Hope you can give me some pointer on how to construct this algorithm.
(I have thought of taking each index of 'B' and check whether they are near to other 'B' but I get stuck)
I am still new to Java, so I want to ask is there is any java function that can check the same occurrence that near to each other in order to count the shape appears?
No, there is no built-in functionality to make this very easy.
And that's the point of the exercise.
Here are some example approaches you could use to solve this problem:
Flood fill:
Convert the input to a matrix. It could be a boolean[][] where you set true where the input is B.
Iterate over the values in the matrix, skipping false values.
When you find a true value, initiate the flood fill:
Increment the count of shapes (you found a new shape)
Recursively replace all adjacent true values with false, incrementing shapeSize count as you go
When all true neighbors (and neighbors of neighbors, and so on) are replaced with false, the shape is fully explored
Continue the iteration where you left off, until you find another true value
Graph theory: find connected components
Convert the input to an undirected graph:
The index of each character can be the vertex id
Create a connection for adjacent pairs of B in the input
Iterate over the vertices of the graph
If a vertex doesn't have yet a component id, use depth-first search to find all the vertices connected to it, assign to all vertices the next component id, incrementing the componentSize count as you go
When there are no more connected vertices, the shape is fully explored
Continue the iteration where you left off, until you find another vertex with no component id
Union find: this is similar to finding the connected components
Method indexof(int ch) returns first index of apearing character in a String. you should cut each string after getting index of first B.
Or you can use indexOf(int ch, int fromIndex) that returns the index within this string of the first occurrence of the specified character, starting the search at the specified index.
int indexCount = 0;
ArrayList<Integer> list = new ArrayList<Integer>();
for(int a = 0; a < count; a++) {
indexCount = array[a].indexOf('B');
list.add(indexCount);
}
System.out.println(list);
Related
For my homework, I need to represents cells in a universe where ' * ' indicates a live cell and an empty space (' ') a dead cell. The following rules are used to determine the status of a particular cell in the next generations:
Any live cell with fewer than two live neighbors dies, as if caused by under population.
Any live cell with two or three live neighbors lives on to the next generation.
Any live cell with more than three live neighbors dies, as if caused by overpopulation.
Any dead cell with exactly three live neighbors becomes a live cell, as if caused by reproduction.
For example, considering the following arrays:
int[][] beehive = {{0,0,0,0,0,0}, {0,0,1,1,0,0}, {0,1,0,0,1,0},
{0,0,1,1,0,0}, {0,0,0,0,0,0}};
int[][] toad = {{0,0,0,0,0,0}, {0,0,1,1,1,0}, {0,1,1,1,0,0}, {0,0,0,0,0,0}};
getNextGenCell(beehive, 1, 3) returns 1, while getNextGenCell(beehive, 3, 1)
returns 0.
getNextGenCell(toad, 0, 3) returns 1, while getNextGenCell(toad, 2, 3)
returns 0.
I am confused on how to proceed with this code. Any suggestion?
My code has to have the following header where int x represents a sub-array and int y represents an element inside that sub-array. The code returns 1 if the cell is alive in the next generation or 0, otherwise.
// A method that gets the cell from the next generation
public static int getNextGenCell(int[][] validUniverse, int x, int y) {
}
You first must determine how you want the logic of your program to flow. In this case, you know there are 8 different cases when traversing the 2D array. These include:
The upper left-hand corner
The upper right-hand corner
The rest of the first row
The lower left-hand corner
The lower right-hand corner
The rest of the last row
The left and right-hand sides of the array
The rest of the array
You will need if statements for each of these cases. The following is an an example of the code for "the rest of the array" case:
if(x!=0&&y!=0&&x!=bees.length-1&&y!=bees[x].length-1&&bees[x][y+1]==1||bees[x][y-1]==1||bees[x+1][y]==1||bees[x-1][y]==1)
Now just finish the other 7 cases, count the amount of "alive" or "dead" cells and modify the array accordingly. Let me know if you have any questions.
I am trying to solve this problem using the least running time.
If we're given a 2D array, we need to return x if there exists a row where all values equal x, and there is a column where all values equal x.
For example, for the following 2d array,
0 3 1
2 3 1
1 1 1
we are supposed to return 1 since the last row and last column are all of same value 1. If no such number exists, we can return -1.
I know there are many ways to solve the problem and most of them are of O(n^2), I'm wondering if there is an efficient way(i.e O(n)) to find such value. (where n represents the number of cells in this array)
Ok, you clarified that you consider O(n) to be the number of values in the 2D array.
I'll outline the approach in pseudo-code, which you can translate to either Java or C++, whichever is your preference. Your question is tagged with both, and the pseudocode is trivial enough to be directly translatable into either C++ or Java. Or Perl. Or Python...
Part 1
Let's start with the first, easy step, how to check whether there's any row that contains the same value. The pseudocode for this is elementary:
start with the 0th row, n=0
check if matrix[n][0] through [n][m-1] (where m is the number of columns in the matrix) contain the same value. If so, you found it.
otherwise, increment n, to go to the next row, until you reach the bottom of the matrix.
You should be able to understand that. This is basic, elementary "Computer Science 101" stuff.
Part 2
Now, let's modify this pseudocode to simultaneously check the columns as well. Modify the above pseudocode as follows.
Create two one-dimensional vectors, call the first one top_values, or something, whose size is m, the number of columns in your matrix. Call the second one flags, it's a vector of boolean flags, also their size is m.
When you scan the 0th row, in the pseudocode given in the first part, copy the values from the 0th row, into top_values. That is, copy matrix[0][x] into top_values[x]. Also set flags[x] to true (you can initialize all flags to true even before you scan the 0th row, it doesn't matter).
When you scan each one of the remaining rows, using the pseudocode given in Part 1, compare matrix[y][x] (where y is the row# you're scanning) against top_values[x]. If they are not the same, set flags[x] to false.
At the end of the pseudocode from part 1, check your flags vector. If any value in it is still true, there's a column in your matrix whose values are the same.
Your homework assignment is to make a slight tweak to the above pseudocode to also tell you which value is the same, in some row or column.
I have a list of Rectangles, created in the usual way with:
List<Rectangle> rects = new ArrayList<>();
Some Rectangles are added (all with non-zero width and height). The number of Rectangles the List contains can be anywhere between 0 and 10,000, and will typically be between 4,000 and 6,000.
The list is sorted by ascending X-coordinate of the Rectangle origin, and then by ascending Y-coordinate for duplicate X-coordinates (though two or more rectangles with the same X-coordinate is rare).
I've verified the sorting is being done correctly (I'm using Collections.sort with a custom comparator).
I need a method that takes as input two ints, x and y, and returns the first Rectangle found containing the point (x,y), or null if no Rectangle in the list contains that point.
public Rectangle findContainingRectangle(int x, int y)
The naive method, which does give the desired functionality, is to just loop through the list and call the contains method on each Rectangle, but that is much too slow.
The List will be modified while the program is running, but at an insignificant rate compared to the rate at which the List needs to be searched, so an algorithm that requires a relatively slow initialization is fine.
I've looked at Collections.binarySearch but couldn't figure out how it might be used. I don't have much experience with Java so if there's another Collection that could be used similarly to a List but better suited to the type of search I need, then that's great (I have read the documentation on things like Maps and Sets but didn't recognize any advantage).
While maintaining a sorted list, you could use a binary search on the 'X' coordinate to find the candidates of the rectangles that contain the wanted 'X', and after which, use binary search on the 'Y' coordinate.
You should implement the binary search yourself, I can't see a way you can use the Collections.binarySearch method.
expected complexity: O(log n) as n the number of rectangles.
(It's a bit more because you might have duplicates)
However ,to do so, you should keep the array sorted while adding other instances, (sort after every insert).
Use HashSet. Map isn't appropriate here since you're not creating key-value pairs, and a Stream doesn't fit in this context either.
Be sure to override equals() and hashCode() in Rectangle, as described here: Why do I need to override the equals and hashCode methods in Java?
You can search your list using parallel stream like this
public Rectangle findContainingRectangle(final int x, final int y) {
List<Rectangle> rectangles = new ArrayList<>();
Rectangle rec = rectangles.parallelStream().filter((r)->{
if(r.getX()==x && r.getY()==y){
return true;
}
return false;
}).findFirst().get();
return rec;
}
Just run binary search a bunch of times - since the probability of same x is low as you say it wont take many times so it will still be logn
a) run binary search
b) remove item if found - and keep index where it was found
c) repeat binary search at a) with the remaining list until null is returned
d) then you have a small array of indexes and you can see which one is the smallest
e) then reinsert the removed elements at the designated spots
You can try and see a performance of a stream. I am not sure it will be fast enough but you can test it.
Rectangle rec = rects.stream().filter((r)->{
return r.contains(x, y);
}).findFirst().get();
You can create a Map.
Map is the best way to associate two values. You can associate the 'x' value and its first position in your List. Then you only have to loop from the first 'x' position to another 'x' in your list.
If you don't find the 'x' on the Map, they don't have the good rectangle on your list.
With this way you don't explore all bad 'x' entry.
I have this problem that I need to solve in the most effecient way.
I have a 2d array that contains the following:
Everything that is a 1 is a "wall" which means you cannot go through it. 2 is the entrance where you "enter" the array or map if you like. 3 are the things we need to find. Here is an example of a map:
1111111
1 3131
2 11111
1 31
1111111
This could be an example of an array that i need to look in. As you can see there is a 3 that is "unreachable, since it's surrounded by a wall "1". Which means that there are two available numbers in this array.
First we need to find the entrance. Since the entrance can be anywhere I need to search the entire array. I have done the following:
int treasureAmount = 0;
Point entrance = new Point(0,0);
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; i++){
if(map[i][j] == 2){
entrance.x =i;
entrance.y =j;
}
}
This takes O(n^2) time, and i don't really see another way to do this, since the entrance can be anywhere.
However i'm not really sure how to find the available numbers effectivly and fast. I thought about while searching the arrays for the entrance i will at the same time find the all the number 3 in the array even though some might not be accessible, and after that i'm not really sure how to effectivly find which are accessible.
You cannot do it better that O(n^2). It will take that much time just to read the array. But then you could do a depth first search to find the reachable 3's in the array. Here is the pseudo code.
main()
{
read array and mark the entrance as ent.x and ent.y and also an array threex[] and threey[] that stores all the exit position.
boolean visited[][]; //stores whether array[i][j] is reachable or not.
dfs(ent.x,ent.y);
for each element in three arrays
{
if(visited[threex[i]][threey[i]]) print ("Reachable");
else print("not reachable", threex[i], threey[i]);
}
}
int dx[]={1,0,-1,0},dy[]={0,1,0,-1}; // dx[i], dy[i] tells whether to move in E,N,W,S respectively.
dfs(int x,int y)
{
visited[x][y]=true;
for(i=0;i<4;i++)//move in all directions
{
int newx=x+dx[i],newy=y+dy[i];
//check if this is within the array boundary
if(newx>=0&&newx<N && newy>=0&&newy<N)
if(!visited[newx][newy] && array[newx][newy]!=1) // check if the node is unvisited and that it is pemissible
dfs(newx,newy);
}
}
Since each array element is taken up not more than once in the dfs function the complexity of the code is O(n^2).
When creating the array, you can keep a list of coordinates of that have the value of 2. You can traverse that list in O(n).
Since both entrance and target items can be anywhere in the array you don't have much choice, but to search everything. So, your entrance search is as efficient as it can be, and regarding the target items I recommend the maze flood fill algorithm.
However, the linked version of the algorithm favorizes one direction (like it is filling it with water, it floods "down"). To be as efficient as it can, you should make it expand in all directions (like you're filling it with gas), e.g.:
2
1 212
0 101 21012
1 212
2
The numbers represent the iterations of expansion. The expansion is made in four directions: left, right, up and down. When you reach the target item, you can find the shortest route simply by backtracking to the adjacent cell neighbour whose iteration index is lesser by one, until you return to the 0 iteration index - the entrance.
I was asked this question in an interview. Suppose you have an ordered dictionary, and are given a list of unordered characters- how would you order these characters by precedence? This dictionary contains words where all the 26 characters are guaranteed to appear. However, note that the size of the dictionary might be anything. The dictionary could be as small as a few words and may not have separate sections for each character e.g., there might be no sections for words beginning with a; although a will appear as part of another word e.g., "bat".
The dictionary might be "ordered" (/sarcasm) as such "zebra', "apple", "cat", "crass", and if you're given the list {a, z, r}, the correct order would be {z, a, r}. Since "zebra" is before "apple" in the dictionary, we know z comes before a in the presedence. Since "apple" comes before "cat", we know a comes before c. Since "cat" comes before "crass", we know that a comes before r. This ordering leaves c and r with ambugious presendece, but since the list of letters was {a, z, r}, we know the solution to be {z, a, r}.
Use a directed graph with 26 vertices, each vertex represents a character. An edge from vertex A to vertex B means in the alphabet B is in front of A.
The first step is to establish such a graph with only vertices but NO edges.
Second, you scan the input dictionary, word by word. And compare each word with the previous word. You should find exact one relationship for each word you scanned. So you add an edge in this graph. Assume the dictionary is correct, there should be no conflicts.
After you finished the dictionary, you output the alphabet by
pick a random vertex, traverse its path until you find the one character that points to nothing. This is the first character in the alphabet. Output it and delete it from the graph.
keep doing 1 until all vertices are deleted.
EDIT:
To better explain this algorithm, let's run it on your sample input.
Input: {"zebra', "apple", "cat", "crass"}
Word 0 and word 1, we immediately know that z comes before a, so we make an edge a->z
Word 1 and word 2, we immediately know that a comes before c, so we make another edge c->a
Word 2 and Word 3, the first letters are the same "c", but the second ones differ, so we learn that a comes before r, so we have another edge r->a
Now all the words are read. Output the order by pick up a vertex randomly (say we pick c), then we have c->a->z in the graph. Output z and delete z from the graph (mark it as NULL). Now pick another one (say we pick r), then we find r->a in the graph. We output a and delete a from graph. Now we pick another one (say we pick c again), there's no path found, so we just output c and delete it. Now we pick the last one, r, there's no path again, so we output r and delete it. Since all vertices are deleted, the algorithm is done.
The output is z, a, c, r. The ordering of "c" and "r" are random since we don't really know their relationship from the input.
From the fact that "zebra' < "apple" < "cat" < "crass", the most efficient way to derive the per-character relationships is to have a loop consider the Nth character of all words, where N is initially 0 yielding the relationships "z" < "a" < "c". That loop can recursively extract relationships for the (N + 1)th character for groups of words with the same prefix (i.e. text in positions <= N). Doing that for N == 1 with same-prefixed "cat" and "crass" yields the relationship "a" < "r".
We can represent known relationships in a 2 dimensional array of x < y truth values.
y\x a b c...r...z
a - N N Y
b -
c Y - Y
r Y -
z N N -
The brute force approach is to iterate over all pairs of characters in the input list (i.e. {a, z, r} -> az, ar, zr) looking up the table for a<z, a<r, z<r: if this is ever false, then swap the characters and restart the whole she-bang. When you make it through the full process without having had to swap any more characters, the output is sorted consistently with the rules. This is a bit like doing a bubble sort.
To make this faster, we can be more proactive about populating cells in our table for implied relationships: for example, we know "z" < "a" < "c" and "a" < "r", so we deduce that "z" < "r". We could do this by running through the "naive" table above to find everything we know about each character (e.g. that z<a and z<c) - then run through what we know about a and c. To avoid excessively deep trees, you could just follow one level of indirection like this, then repeat until the table was stable.
Based on how you describe the problem, your example is incorrect. Your answer should be {z,r,a}. However that may be, below is a code that solves the problem. You can modify it to return an order different from my supposed {z,r,a}.
Set<Character> charPrecedence(List<String> dictionary, char[] letters){
Set<Character> result = new HashSet<Character>();
//since your characters are the 26 letters instead of the 256 chars
// a bit vector won't do; you need a map or set
Set<Character> alphabets = new HashSet<Character>();
for(char c: letters)
alphabets.add(c);
//now get to work
for(String word: dictionary){
if(alphabets.isEmpty()) return result;
for(char c: word.toCharArray()){
if(alphabets.remove(c))
result.add(c);
}
}
//since the dictionary is guaranteed to contain all the 26 letters,
//per the problem statement, then at this point your work is done.
return result;
}
best case O(1); worst case O(n) where n is the number of characters in the dictionary, i.e., one particular letter appears only once and is the last character you check.