[Issue 6] two dimensional array that should be known before bat interview

Time:2021-8-19

Maybe you’ve seen a lot of stories about how to ask some strange algorithm questions in the interview. To tell you the truth, it’s no shame that you can’t tear the red and black tree by hand. It’s difficult to make dynamic planning. It doesn’t matter if you don’t have ideas, but I still hope you can understand the problems related to two-dimensional arrays.

Unlike some strange algorithm problems that let you interview to build a nuclear bomb, the two-dimensional array algorithm problem can investigate the logic ability and program boundary problems, and a considerable part of the two-dimensional array can be solved by recursion, which can be said to be a necessary problem for programmers at home.

The subscript law and boundary of array are investigated

For such problems, the focus is to find the law from the subscript of the array. When writing code, we should pay attention to the boundary of the program. It is common to print two-dimensional array in zigzag, Snake Print two-dimensional array, Yang Hui triangle and so on.

Yang Hui triangle

Leetcode.118, easy

subject

Given a nonnegative integer NumRows, the first NumRows of Yang Hui triangle are generated.
Example:

Input: 5

Output:

[

 [1],<br> 
[1,1],<br> 

[1,2,1],

[1,3,3,1],

[1,4,6,4,1]
]

thinking

By observing the examples given, we can find the rules. For example, for Arr1 = [1,2,1] and arr2 = [1,3,3,1]:

[Issue 6] two dimensional array that should be known before bat interview
We can see the rule:

  1. arr2[0] = 1
  2. arr2[1] = arr1[0] + arr1[1]
  3. arr2[2] = arr1[1] + arr1[2]
  4. arr[3] = 1

The reverse idea is:

  • When traversing Arr1 and index = 0, arr2.push (1)
  • If index = arr1.length-1, arr2.push (1)
  • Otherwise, arr2.push (Arr1 [index] + Arr1 [index + 1])

code

/**
 * @param {number} numRows
 * @return {number[][]}
 */
var generate = function(n) {
  if(n === 0)
    return [];
  if(n === 1)
    return [ [1] ];
  
  let res = [[1]];
  
  for(let i = 1;i < n;i++) {
    let lastArr = res[i-1];
    let newArr = [];
    for(let j = 0;j < lastArr.length;j++) {
      if(j === 0)
          newArr.push(1);
      if(j === lastArr.length-1)
        newArr.push(1);
      else {
        newArr.push(lastArr[j]+lastArr[j+1]);
      }
    }
    
    res.push(newArr);
  }
  return res;
};

Diagonal traversal of two-dimensional array

Leetcode.498, medium difficulty

subject

Given a matrix with m x n elements (M rows and N columns), please return all elements in the matrix in the order of diagonal traversal, as shown in the figure below.
Example:

Input:
[

[ 1, 2, 3 ],

[ 4, 5, 6 ],

[ 7, 8, 9 ]

]

Output: [1,2,4,7,5,3,6,8,9]

thinking

Observe an example. For the following two-dimensional array, the diagonal traversal order is as follows:

  1. (0,0)
  2. (0,1), (1,0)
  3. (2,0), (1,1), (0,2)
  4. (0,3), (1,2), (2,1)
  5. (2,2), (1,3)
  6. (2,3)

[

A, B, C, D,

E, F, G, H,

I, J, K, L

]

Some rules can be seen:

  • According to the diagonal line printed once, it needs to be printed 6 times, that is, the number of rows + the number of columns – 1 time
  • If count = 0 is calculated according to the first time, if count is less than the number of rows, then x = count and y = count-x, otherwise x = number of rows – 1 and y = count-x, the same is true for the number of columns

code

/**
 * @param {number[][]} matrix
 * @return {number[]}
 */
var findDiagonalOrder = function(matrix) {
    if(matrix === null || matrix.length === 0 || matrix[0].length === 0)
        return [];
    
    let rows = matrix.length;
    let cols = matrix[0].length;
    let count = 0;
    let res = [];
    
    while(count < rows+cols-1) {
        let r1 = count < rows ? count : rows-1;
        let c1 = count - r1;
        while(r1 >= 0 && c1 < cols) {
            res.push(matrix[r1][c1]);
            r1--;
            c1++;
        }
        
        count++;
        if(count >= rows+cols-1)
            break;
        
        let c2 = count < cols ? count : cols-1;
        let r2 = count - c2;
        while(c2 >= 0 && r2 < rows) {
            res.push(matrix[r2][c2]);
            r2++;
            c2--;
        }
        count++
    }
    
    return res;
};

Spiral matrix

Leetcode.54, medium difficulty

subject

Given a matrix containing m x n elements (M rows, n columns), please return all the elements in the matrix in a clockwise spiral order.

Example 1:

Input:
[

[ 1, 2, 3 ],

[ 4, 5, 6 ],

[ 7, 8, 9 ]
]

Output: [1,2,3,6,9,8,7,4,5]

Example 2:

Input:
[

[1, 2, 3, 4],

[5, 6, 7, 8],

[9,10,11,12]
]

Output: [1,2,3,4,8,12,11,10,9,5,6,7]

thinking

From the example given in the title, we can see that the spiral ergodic matrix is actually ergodic layer by layer clockwise. Pay attention to the division of boundaries and the treatment of special cases, such as one row and one column.

[Issue 6] two dimensional array that should be known before bat interview

code

/**
 * @param {number[][]} matrix
 * @return {number[]}
 */
var traverseLayer = function(m, startRow, endRow, startCol, endCol, res) {
    if(startRow === endRow) {
    //One column
        for(let i = startCol;i <= endCol;i++) {
            res.push(m[startRow][i]);
        }
    } else if(startCol === endCol) {
        for(let i = startRow;i <= endRow;i++) {
            res.push(m[i][startCol]);
        }
    } else {
        let curR = startRow;
        let curC = startCol;
        
        while(curC < endCol) {
            res.push(m[curR][curC]);
            curC++;
        }
        while(curR < endRow) {
            res.push(m[curR][curC]);
            curR++;
        }
        while(curC > startCol) {
            res.push(m[curR][curC]);
            curC--;
        }
        while(curR > startRow) {
            res.push(m[curR][curC]);
            curR--;
        }
    }
}

var spiralOrder = function(matrix) {
    if(matrix === void 0 || matrix.length === 0 || matrix[0].length === 0)
        return [];
    
    let res = [];
    let startRow = 0;
    let endRow = matrix.length-1;
    let startCol = 0;
    let endCol = matrix[0].length-1;
    
    
    while(startRow <= endRow && startCol <= endCol) {
        traverseLayer(matrix, startRow, endRow, startCol, endCol, res);
        startRow++;
        endRow--;
        startCol++;
        endCol--;
    }
    
    return res;
};

Examine recursive ideas

For this kind of problem, the most important thing is to note that it can not be solved simply by finding the law of array subscript. The problem should be abstracted into the idea of recursion, including recursive entry, recursive call and recursive end condition.

Wechat Moments

Leetcode.547, medium difficulty

subject

There are n students in the class. Some of them are friends, others are not. Their friendship is transitive. If we know that a is a friend of B and B is a friend of C, then we can think that a is also a friend of C. The so-called circle of friends refers to the collection of all friends.

Given a matrix M of n * n, it represents the friend relationship between middle school students in the class. If Mi = 1, it means that I and j students are known to be friends with each other, otherwise it means they don’t know. You must output the total number of known circles of friends among all students.

Example 1:

Input:

[[1,1,0],

[1,1,0],

[0,0,1]]

Output: 2

Note: it is known that student 0 and student 1 are friends with each other. They are in a circle of friends.
The second student is in a circle of friends. So return 2.

Example 2:

Input:

[[1,1,0],

[1,1,1],

[0,1,1]]

Output: 1

Note: it is known that student 0 and student 1 are friends with each other, and student 1 and student 2 are friends with each other, so student 0 and student 2 are also friends, so they are in a circle of friends and return 1.

be careful:
N is in the range of [1200].
For all students, there is mi = 1.
If there is mi = 1, there is MJ = 1.

thinking

Take a look at the example of this question. You can see that if arr [0,1] = 1, 0 and 1 are friends, then you need to check whether 1 and other people are friends, and then check them in turn. At this point, you can consider the depth first search method.

code

/**
 * @param {number[][]} M
 * @return {number}
 */
var findCircleNum = function(M) {
    //Depth first
    let visited = [];
    for(let i = 0;i < M.length;i++) {
        visited.push(false);    
    }
    
    let res = 0;
    for(let i = 0;i < visited.length;i++) {
        if(visited[i]) 
            continue;
        traverse(M, i, visited);
        res++;
    }
    
    return res;
};

function traverse(M, cur, visited) {
    visited[cur] = true;
    for(let i = 0;i < M.length;i++) {
        if(visited[i] || !M[cur][i])
            continue;
        traverse(M, i, visited);
    }
}

Maximum area of the island

Leetcode.695, medium difficulty

subject

Given a non empty two-dimensional array grid containing some 0 and 1, an island is a combination of 1 (representing land) in four directions (horizontal or vertical). You can assume that the four edges of a two-dimensional matrix are surrounded by water.

Find the largest island area in the given two-dimensional array( If there are no islands, the return area is 0.)

Example 1:

[[0,0,1,0,0,0,0,1,0,0,0,0,0],
[0,0,0,0,0,0,0,1,1,1,0,0,0],
[0,1,1,0,1,0,0,0,0,0,0,0,0],
[0,1,0,0,1,1,0,0,1,0,1,0,0],
[0,1,0,0,1,1,0,0,1,1,1,0,0],
[0,0,0,0,0,0,0,0,0,0,1,0,0],
[0,0,0,0,0,0,0,1,1,1,0,0,0],
[0,0,0,0,0,0,0,1,1,0,0,0,0]]

For the given matrix above, 6 should be returned.

Note that the answer should not be 11, because the island can only contain ‘1’ in four horizontal or vertical directions.

Example 2:

[[0,0,0,0,0,0,0,0]]

For the given matrix above, return 0.

Note: the length and width of a given matrix grid do not exceed 50.

thinking

For matrices such as [[1,1,0,0,0], [1,1,0,0,0], [0,0,1,1], [0,0,0,1,1]], start from the 1 in the top left corner, and then check whether its four sides (up, down, left and right) are 1, and its up, down, left and right are 1. If it is 1, it can be added 1. If it is 0, it will not be processed. At this point, it can be determined that recursion can be used, That is, there is a process that calls itself; There is a detail here. The processed 1 needs to be set to 0, otherwise there will be repeated calculation.

The code is as follows:

/**
 * @param {number[][]} grid
 * @return {number}
 */
var maxAreaOfIsland = function(grid) {
    if(grid === null || grid.length === 0)
        return 0;
    
    let res = 0;
    for(let i = 0;i < grid.length;i++) {
        for(let j = 0;j < grid[0].length;j++) {
            if(grid[i][j] === 1)
                res = Math.max(res, help(grid, i, j));
        }
    }
    
    return res;
};

var help = function(grid, i, j) {
    grid[i][j] = 0;
    
    let sum = 1;
    if(i > 0 && grid[i-1][j] === 1)
        sum += help(grid, i-1, j);
    if(i < grid.length-1 && grid[i+1][j] === 1) 
        sum += help(grid, i+1, j);
    if(j > 0 && grid[i][j-1] === 1)
        sum += help(grid, i, j-1);
    if(j < grid[0].length-1 && grid[i][j+1] === 1)
        sum += help(grid, i, j+1);
    
    return sum;
}

Welcome to WeChat official account, fe-yagushou.

[Issue 6] two dimensional array that should be known before bat interview