Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Find a String in a 2 dimensional Array

This is a interview question which needs to be optimized for time.

Suppose you have a 2 dimensional Array and you have a String say "Amazon" inside the Array such that the individual characters can be present from Left to Right, Right to Left, Top to down and down to up.

I will explain with example :

char[][] a = {
            {B,B,A,B,B,N},
            {B,B,M,B,B,O},
            {B,B,A,B,B,Z},
            {N,O,Z,B,B,A},
            {B,B,B,B,B,M},
            {B,B,B,B,B,A}
    };

The above Array has two Amazon Strings. You need to return the count of number of such strings present.

like image 427
Geek Avatar asked Jul 19 '16 05:07

Geek


People also ask

How do you find the elements of a 2D array?

An element in 2-dimensional array is accessed by using the subscripts. That is, row index and column index of the array. int x = a[1,1]; Console.

Is a String a 2D array?

In C++, a string is usually just an array of (or a reference/points to) characters that ends with the NULL character '\0'. A string is a 1-dimensional array of characters and an array of strings is a 2-dimensional array of characters.

How many strings per row of a 2-dimensional array?

Depending on the persistence of your grid and the number of searches being performed, you may find it more efficient to pre-convert your 2-dimensional array of characters into a one dimensional array of strings (one string per row).

How to search any element in a 2D array?

While searching in the 2D array is exactly the same but here all the cells need to be traversed and In this way, any element is searched in a 2D array. // This code is contributed by ukasp. The Time Complexity of linear search in a 2D array is O (N * M) where N is the number of rows and M is the number of columns.

How to find row and column numbers in a two-dimensional array?

In this example, the goal is to locate the row and column number for a given value in a two-dimensional array. To get the row number, the data is compared to the max value, which generates an array of TRUE FALSE results. These are multiplied by the result of ROW (data) which generates and array of row numbers associated with the named range "data":

How to display two-dimensional array of strings in C++?

The two-dimensional array of strings can be displayed by using loops. To display we can use printf (), puts (), fputs () or any other methods to display the string.


3 Answers

I have done a simple bfs, every time the first character of the string toFind (in your case AMAZON) matches a character in the 2D Array. A simple visited 2D array is used to check for marked characters in one iteration:

public class FindStrings {

private static int count = 0;       // Final Count

public static void find(Character[][] a, String toFind) {

    int rows = a.length;
    int col = a[0].length;

    boolean[][] visited = new boolean[a.length][a[0].length];

    for (int i = 0; i < rows; i++) {
        for (int j = 0; j < col; j++) {
            if (a[i][j] == toFind.charAt(0)) {
                findUtil(visited, a, i, j, 0, toFind, new StringBuilder(), rows - 1, col - 1,new ArrayList<String>());
                visited[i][j] = false;
            }
        }
    }

}

private static void findUtil(boolean[][] visited, Character[][] a, int i, int j, int index, String toFind, StringBuilder result, int R, int C,ArrayList<String> list) {

    result.append(a[i][j]);
    //This list just prints the entire Path
    list.add(i+"-"+j);
    if (index == toFind.length() - 1 && result.toString().equals(toFind)) {
        System.out.println(list.toString());
        count++;
        return;
    }
    visited[i][j] = true; // Just to mark the character so that one character is not visited twice for a string match
    int nextIndex = index + 1; //Next index of the String to be compared

    int nextR, nextC;

    //Down
    if (i + 1 >= 0 && j >= 0 && i + 1 <= R && j <= C && !visited[i + 1][j] && a[i + 1][j] == toFind.charAt(nextIndex)) {
        nextR = i + 1;
        nextC = j;
        findUtil(visited, a, nextR, nextC, nextIndex, toFind, new StringBuilder(result), R, C,new ArrayList<>(list));
        //Every time we are done with the next character in the 2D Array we mark it visited
        visited[nextR][nextC] = false;
    }
    //Right
    if (i >= 0 && j + 1 >= 0 && i <= R && j + 1 <= C && !visited[i][j + 1] && a[i][j + 1] == toFind.charAt(nextIndex)) {
        nextR = i;
        nextC = j + 1;
        findUtil(visited, a, nextR, nextC, nextIndex, toFind, new StringBuilder(result), R, C,new ArrayList<>(list));
        visited[nextR][nextC] = false;
    }
    //Left
    if (i >= 0 && j - 1 >= 0 && i <= R && j - 1 <= C && !visited[i][j - 1] && a[i][j - 1] == toFind.charAt(nextIndex)) {
        nextR = i;
        nextC = j - 1;
        findUtil(visited, a, nextR, nextC, nextIndex, toFind, new StringBuilder(result), R, C,new ArrayList<>(list));
        visited[nextR][nextC] = false;
    }
    //Up
    if (i - 1 >= 0 && j >= 0 && i - 1 <= R && j <= C && !visited[i - 1][j] && a[i - 1][j] == toFind.charAt(nextIndex)) {
        nextR = i - 1;
        nextC = j;
        findUtil(visited, a, nextR, nextC, nextIndex, toFind, new StringBuilder(result), R, C,new ArrayList<>(list));
        visited[nextR][nextC] = false;
    }


}

public static int getCount() {
    return count;
}

public static void main(String[] args) {

    Character[][] a = new Character[][]{
            {'B', 'B', 'A', 'B', 'B', 'N'},
            {'B', 'B', 'M', 'B', 'B', 'O'},
            {'B', 'B', 'A', 'B', 'B', 'Z'},
            {'B', 'O', 'Z', 'O', 'N', 'A'},
            {'B', 'B', 'O', 'Z', 'B', 'M'},
            {'B', 'B', 'N', 'A', 'M', 'A'}
    };

    String toFind = "AMAZON";

    find(a, toFind);
    System.out.println(getCount());

}
like image 118
poorvank Avatar answered Oct 17 '22 22:10

poorvank


You can run a BFS from each cell of the matrix having 'A' and count the number of way Amazon can be built. Finally add them all.

Edges: A adjacent(up,down,left,right) node(cell) have a directed edge from the current node(cell) if it contains the next character of Amazon. Just example, all adjacent node having 'N' have a directed edge from the node having 'O'.

like image 1
MMHossain Avatar answered Oct 17 '22 21:10

MMHossain


You gave only one example. If:

  • All the 'filler' characters are always something not in the string
  • The string is always complete and not split
  • The string has at least one non repeating letter

Then you just need to count how many of those non repeating letters there are. For example, with 'AMAZON', you just need to count how many 'Z' (or 'M', or 'O', or 'N') are in the array.

That's not as general as a path finding algorithm but definitely faster.

like image 1
ChatterOne Avatar answered Oct 17 '22 21:10

ChatterOne