Complete leetcode's intensive lecture on algorithm interview in Dachang 24. Other types of questions

Complete leetcode's intensive lecture on algorithm interview in Dachang 24. Other types of questions

Video Explanation (efficient learning): Click to learn

catalog:

1. Introduction

2. Time and space complexity

3. Dynamic planning

4. Greed

5. Binary search

6. Depth first & breadth first

7. Double pointer

8. Sliding window

9. Bit operation

10. Recursion & divide and conquer

11 Pruning & backtracking

12. Reactor

13. Monotone stack

14. Sorting algorithm

15. Linked list

16.set&map

17. Stack

18. Queue

19. Array

20. String

21. Trees

22. Dictionary tree

23. Consolidation

24. Other types of questions

65. Significant figures (hard)

Graph is an abstract model of network structure. It is a group of nodes connected by edges

The graph can identify any binary relationship, such as road and flight

Representation of Graphs

  • adjacency matrix
  • Adjacency table
  • Idea: finite state machine, traverse the string, constantly convert the state, and see whether the final state is a valid state
  • Complexity: time complexity O(n), n is the length of the string, traverses n times, and each state transition is O(1). Space complexity O(1)

js:

//1.2   2e10
//--6   2e
var isNumber = function(s) {
    const graph = {//Temporary connection table composed of points and edges
        0:{ 'blank': 0, 'sign': 1, '.': 2, 'digit': 6 },
        1:{ 'digit': 6, '.': 2 },
        2:{ 'digit': 3 },
        3:{ 'digit': 3, 'e': 4 },
        4:{ 'digit': 5, 'sign': 7 },
        5:{ 'digit': 5 },
        6:{ 'digit': 6, '.': 3,  'e': 4 },
        7:{ 'digit': 5 },
    }

    let state = 0;//Initial state

    for (let c of s.trim()) {//Circular string
        if (c >= '0' && c <= '9') {
            c = 'digit';
        } else if (c === ' ') {
            c = 'blank';
        } else if(c === '+' ||  c === '-') {
            c = 'sign'
        }

        state = graph[state][c];//Return to next status

        if (state === undefined) {//false is not returned in the temporary table after the state transition
            return false;
        }

    }
    
    if (state == 3 || state == 5 || state == 6) {//The status is one of 3, 5 and 6, and the description is a significant number
        return true;
    }

    return false;
};

836. Rectangular overlap (easy)

  • Complexity: time complexity O(1), space complexity O(1)

js:

var isRectangleOverlap = function(rec1, rec2) {
    const [x1, y1, x2, y2] = rec1;
    const [x3, y3, x4, y4] = rec2;
    return !(x1 >= x4 || x3 >= x2 || y3 >= y2 || y1 >= y4);
};

java:

class Solution {
    public boolean isRectangleOverlap(int[] rec1, int[] rec2) {
        return !(rec1[2] <= rec2[0] || rec2[2] <= rec1[0] || rec1[3] <= rec2[1] || rec2[3] <= rec1[1]);
    }
}

417. Pacific Atlantic currents( medium)

  • Idea: prepare two matrices indicating whether it can flow to a coastline, and "upstream" along the coastline. Finally, count the coordinates of the two oceans
  • Complexity: time complexity O(m*n),m and N are the length and width of the coordinate matrix respectively. Spatial complexity O(m * n)
the pacific ocean ~   ~   ~   ~   ~ 
       ~  1   2   2   3  (5) *
       ~  3   2   3  (4) (4) *
       ~  2   4  (5)  3   1  *
       ~ (6) (7)  1   4   5  *
       ~ (5)  1   1   2   4  *
          *   *   *   *   * Atlantic

js:

var pacificAtlantic = function(matrix) {
    if(!matrix || !matrix[0]) { return []; }
    const m = matrix.length;
    const n = matrix[0].length;
   //An array of whether a certain coordinate can be reached upstream from the Pacific or Atlantic Ocean indicates that it can flow to an ocean
    const flow1 = Array.from({ length: m }, () => new Array(n).fill(false));
    const flow2 = Array.from({ length: m }, () => new Array(n).fill(false));
    
    const dfs = (r, c, flow) => {
        flow[r][c] = true;
        [[r-1, c], [r+1, c], [r, c-1], [r, c+1]].forEach(([nr, nc]) => {
            if(
                //Prevention of cross-border
                nr >= 0 && nr < m &&
                nc >= 0 && nc < n &&
                //Only unmarked coordinates can continue recursion to prevent dead loops
                !flow[nr][nc] &&
                //Make sure it's upstream
                matrix[nr][nc] >= matrix[r][c]
            ) {
                dfs(nr, nc, flow)
            }
        })
    }
    //Upstream
    for(let r = 0; r<m; r+=1) {
        dfs(r, 0, flow1);
        dfs(r, n-1, flow2)
    }
    for(let c = 0; c <n; c += 1) {
        dfs(0, c, flow1);
        dfs(m-1, c, flow2)
    }
    //Count the coordinates of the flow direction of both oceans
    const res = []
    for(let r = 0; r < m; r += 1) {
        for(let c = 0; c < n; c += 1) {
            if(flow1[r][c] && flow2[r][c]) {
                res.push([r, c])
            }
        }
    }
    return res;
};

java:

public class pacificAtlantic {
    private static int[][] dires = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}};
    private int m, n;
    private int[][] matrix;

    public List<List<Integer>> pacificAtlantic(int[][] matrix) {
        List<List<Integer>> res = new ArrayList<>();
        m = matrix.length;
        if (m == 0)
            return res;
        n = matrix[0].length;
        if (n == 0)
            return res;
        this.matrix = matrix;
        boolean[][] canReachP = new boolean[m][n];
        boolean[][] canReachA = new boolean[m][n];
        for (int i = 0; i < n; i++) {
            dfs(0, i, canReachP);
            dfs(m - 1, i, canReachA);
        }
        for (int i = 0; i < m; i++) {
            dfs(i, 0, canReachP);
            dfs(i, n - 1, canReachA);
        }
        for(int i = 0; i < m; i++){
            for(int j = 0; j < n; j++){
                if(canReachA[i][j] && canReachP[i][j]){
                    List<Integer> temp = new ArrayList<>();
                    temp.add(i);
                    temp.add(j);
                    res.add(temp);
                }
            }
        }
        return res;
    }

    private void dfs(int x, int y, boolean[][] canReach) {
        canReach[x][y] = true;
        for (int i = 0; i < 4; i++) {
            int newX = x + dires[i][0];
            int newY = y + dires[i][1];
            if (isIn(newX, newY) && matrix[x][y] <= matrix[newX][newY] && !canReach[newX][newY]) {
                dfs(newX, newY, canReach);
            }
        }
    }

    private boolean isIn(int x, int y) {
        return x >= 0 && x < m && y >= 0 && y < n;
    }
}

133. Clone map (medium)

Method 1:dfs
  • Idea: depth first traversal, recursively create the relationship between each node and adjacent nodes
  • Complexity: time complexity O(n), n represents the number of nodes. Spatial complexity O(n), depth of recursion

js:

var cloneGraph = function(node) {
    if(!node) return;
    const visited = new Map();//Store traversed nodes
    const dfs = (n) => {
        const nCopy = new Node(n.val);//copy node 
        visited.set(n, nCopy);//The node value and the new node are stored in visited with key value pairs
        (n.neighbors || []).forEach(ne => {
            if(!visited.has(ne)) {
                dfs(ne);//Recursive traversal of adjacent nodes
            }
            nCopy.neighbors.push(visited.get(ne));//Copy adjacent nodes
        })
    }
    dfs(node);//Depth first traversal
    return visited.get(node);//Returns the newly created node in visited
};

java:

class Solution {
    private HashMap <Node, Node> visited = new HashMap <> ();
    public Node cloneGraph(Node node) {
        if (node == null) {
            return node;
        }

        if (visited.containsKey(node)) {
            return visited.get(node);
        }

        Node cloneNode = new Node(node.val, new ArrayList());
        visited.put(node, cloneNode);

        for (Node neighbor: node.neighbors) {
            cloneNode.neighbors.add(cloneGraph(neighbor));
        }
        return cloneNode;
    }
}
Method 1:bfs
  • Idea: breadth first traverse each node and copy the relationship between nodes
  • Complexity: time complexity O(n), n represents the number of nodes. Space complexity O(n), space of queue

js:

var cloneGraph = function(node) {
    if(!node) return;
    const visited = new Map();
    visited.set(node, new Node(node.val));//The node value and the new node are stored in visited with key value pairs
    const q = [node];
    while(q.length) {
        const n = q.shift()//Out of the team
        (n.neighbors || []).forEach(ne => {//Loop adjacent nodes
            if(!visited.has(ne)) {//Join the queue without accessing
                q.push(ne);
                visited.set(ne, new Node(ne.val));
            }
            visited.get(n).neighbors.push(visited.get(ne));//Copy adjacent nodes
        })
    }
    return visited.get(node);
};

java:

class Solution {
    public Node cloneGraph(Node node) {
        if (node == null) {
            return node;
        }
        HashMap<Node, Node> visited = new HashMap();

        LinkedList<Node> queue = new LinkedList<Node> ();
        queue.add(node);
        visited.put(node, new Node(node.val, new ArrayList()));

        while (!queue.isEmpty()) {
            Node n = queue.remove();
            for (Node neighbor: n.neighbors) {
                if (!visited.containsKey(neighbor)) {
                    visited.put(neighbor, new Node(neighbor.val, new ArrayList()));
                    queue.add(neighbor);
                }
                visited.get(n).neighbors.add(visited.get(neighbor));
            }
        }

        return visited.get(node);
    }
}

605. Flower planting (easy)

  • Idea: traversal. If you can plant flowers, the position is 0, and the front and rear positions are not 1
  • Complexity: time complexity O(n), space complexity O(1)

js:

var canPlaceFlowers = function (flowerbed, n) {
    let count = 0
    for (let i = 0, length = flowerbed.length; i < length; i++) {
      //The current position is 0, and neither front nor back is 1. Consider the special cases at the front and last
        if (flowerbed[i] === 0 && flowerbed[i - 1] !== 1 && flowerbed[i + 1] !== 1) {
            count++
            i++
        }
    }
    return count >= n
};

java:

class Solution {

    public boolean canPlaceFlowers(int[] flowerbed, int n) {

        int m = flowerbed.length;
        
        int count = 0;
        for (int i=0;i<m;i++) {

            if (flowerbed[i] == 0 && (i == m - 1 || flowerbed[i + 1] == 0) && (i == 0 || flowerbed[i - 1] == 0)) {

                flowerbed[i] = 1;
                count++;
            }
        }
        return count >= n;
    }
}

89. Gray code (medium)

  • Idea: the variable pre is initially 1, constantly moving to the left, ans stores the results, and adds pre to the first number of each cycle
  • Complexity: time complexity O(n^2). Space complexity O(1)

js:

var grayCode = function(n) {
    let ans = [0];
    let pre = 1;
    for(let i = 0;i<n;i++){
        for(let j = ans.length - 1;j>=0;j--){
            ans.push(pre + ans[j]);
        }
        pre <<= 1;
    }
    return ans;
};

java:

class Solution {
    public List<Integer> grayCode(int n) {
        List<Integer> res = new ArrayList<Integer>() {{ add(0); }};
        int head = 1;
        for (int i = 0; i < n; i++) {
            for (int j = res.size() - 1; j >= 0; j--)
                res.add(head + res.get(j));
            head <<= 1;
        }
        return res;
    }
}

914. Card grouping( easy)

  • Idea: count the frequency of each number and find out whether the maximum common divisor is greater than 1
  • Complexity: time complexity O(n), space complexity O(n)

js:

var hasGroupsSizeX = function(deck) {
    let map = new Map()
    for(let n of deck){//Statistical frequency
        map.set(n,map.has(n)?map.get(n)+1:1)
    }
    let arr = [...map.values()]
    let res = arr[0]
    return arr.every(i => (res = gcd(res, i)) > 1)//Find whether the maximum common divisor is greater than 1

};
//Rolling division 4,2
let gcd = (a, b) => (b === 0 ? a : gcd(b, a % b))

java:

class Solution {
    public boolean hasGroupsSizeX(int[] deck) {
        if(deck.length == 0 || deck.length == 1) return false;
        int[] count = new int[10000];
        for (int num: deck) count[num]++;
        return Arrays.stream(count).reduce(this::gcd).getAsInt() > 1;
    }
    private int gcd(int a, int b) {
        return b == 0? a: gcd(b, a % b);
    }
}

41. Missing first positive number (hard)

  • Idea: loop num, if the current element is between (0, num.lenght], and num [num [i] - 1]! = num [i], then exchange the position, and then loop the array after the position to judge the first missing positive number
  • Complexity: time complexity O(n), space complexity O(1)

js:

var firstMissingPositive = function(nums) {
    for(let i = 0; i < nums.length; i++){
       //Loop nums. If the current element is between (0,nums.lenght], and nums [nums [i] - 1]! = nums [i], the position is exchanged
        while(nums[i] > 0 && nums[i] <= nums.length && nums[nums[i]-1] != nums[i] ){
            const temp = nums[nums[i]-1];
            nums[nums[i]-1] = nums[i];
            nums[i] = temp;
        }
    }
    for(let i = 0; i < nums.length; i++){//Loop through the array after exchanging positions to determine the first missing positive number
        if(nums[i] != i+1){
            return i+1;
        }
    }
  // [1,2,3]
    return nums.length + 1;

};

java:

class Solution {
    public int firstMissingPositive(int[] nums) {
        int n = nums.length;
        for (int i = 0; i < n; ++i) {
            while (nums[i] > 0 && nums[i] <= n && nums[nums[i] - 1] != nums[i]) {
                int temp = nums[nums[i] - 1];
                nums[nums[i] - 1] = nums[i];
                nums[i] = temp;
            }
        }
        for (int i = 0; i < n; ++i) {
            if (nums[i] != i + 1) {
                return i + 1;
            }
        }
        return n + 1;
    }
}

48. Rotate the image (medium)

  • Idea: first flip along the horizontal axis, and then flip along the main diagonal
  • Complexity: time complexity O(n^2), space complexity O(1)

js:

var rotate = function(matrix) {
    const n = matrix.length;
    //Horizontal axis flip
    for (let i = 0; i < Math.floor(n / 2); i++) {
        for (let j = 0; j < n; j++) {
            [matrix[i][j], matrix[n - i - 1][j]] = [matrix[n - i - 1][j], matrix[i][j]];
        }
    }
    //Main diagonal flip
    for (let i = 0; i < n; i++) {
        for (let j = 0; j < i; j++) {
            [matrix[i][j], matrix[j][i]] = [matrix[j][i], matrix[i][j]];
        }
    }
};

java:

class Solution {
    public void rotate(int[][] matrix) {
        int n = matrix.length;
        //Horizontal axis flip
        for (int i = 0; i < n / 2; ++i) {
            for (int j = 0; j < n; ++j) {
                int temp = matrix[i][j];
                matrix[i][j] = matrix[n - i - 1][j];
                matrix[n - i - 1][j] = temp;
            }
        }
        //Main diagonal flip
        for (int i = 0; i < n; ++i) {
            for (int j = 0; j < i; ++j) {
                int temp = matrix[i][j];
                matrix[i][j] = matrix[j][i];
                matrix[j][i] = temp;
            }
        }
    }
}

54. Spiral matrix (medium)

  • Idea: simulate the order of rotation
  • Complexity: time complexity O(mn), space complexity O(1)

js:

var spiralOrder = function (matrix) {
    if (matrix.length == 0) return []
    const res = []
    let top = 0, bottom = matrix.length - 1, left = 0, right = matrix[0].length - 1
    while (top <= bottom && left <= right) {//Cycle condition
        for (let i = left; i <= right; i++) res.push(matrix[top][i])//Cycle through the top line above++
        top++
        for (let i = top; i <= bottom; i++) res.push(matrix[i][right])//Loop the right line--
        right--
        if (top > bottom || left > right) break
        for (let i = right; i >= left; i--) res.push(matrix[bottom][i])
        bottom--
        for (let i = bottom; i >= top; i--) res.push(matrix[i][left])
        left++
    }
    return res
};

java

class Solution {
    public List<Integer> spiralOrder(int[][] matrix) {
        List<Integer> ans = new ArrayList<>();
        int top = 0, bottom = matrix.length - 1;
        int left = 0, right = matrix[0].length - 1;
        
        while(true){
            for(int i = left ; i <= right ; ++i) ans.add(matrix[top][i]);
            if(++top > bottom) break;

            for(int i = top ; i <= bottom ; ++i) ans.add(matrix[i][right]);
            if(--right < left) break;

            for(int i = right ; i >= left ; --i) ans.add(matrix[bottom][i]);
            if(--bottom < top) break;

            for(int i = bottom ; i >= top ; --i) ans.add(matrix[i][left]);
            if(++left > right) break;
        }
        return ans;
    }
}

56. Consolidation interval (medium)

  • Idea: the intervals are sorted according to the starting position. When curr [1] > = interval [0] indicates overlap, update the right boundary of the current curr. If it is not repeated, add result and update the interval
  • Complexity: time complexity O(nlogn), sorting complexity. Space complexity O(logn), sorting extra space

js:

// curr:     [1,3]
// interval: [2,6]
// curr:    ---
// interval:   -----
var merge = function (intervals) {
    if (intervals.length < 2) {
        return intervals;
    }
    intervals.sort((a, b) => a[0] - b[0]);//Sort by start position
    let curr = intervals[0];//The current interval curr is initialized to intervals[0]
    let result = [];

    for (let interval of intervals) {//Traversal intervals
        if (curr[1] >= interval[0]) {//When curr [1] > = interval [0], the description overlaps
            curr[1] = Math.max(curr[1], interval[1]);//Updates the right boundary of the current curr
        } else {
            result.push(curr);//Join result without overlap
            curr = interval;//Update interval
        }
    }
    result.push(curr);
    return result;
};

java:

class Solution {
    public int[][] merge(int[][] intervals) {
        List<int[]> res = new LinkedList<>();
        Arrays.sort(intervals, (o1, o2) -> Integer.compare(o1[0], o2[0]));

        int start = intervals[0][0];
        for (int i = 1; i < intervals.length; i++) {
            if (intervals[i][0] > intervals[i - 1][1]) {
                res.add(new int[]{start, intervals[i - 1][1]});
                start = intervals[i][0];
            } else {
                intervals[i][1] = Math.max(intervals[i][1], intervals[i - 1][1]);
            }
        }
        res.add(new int[]{start, intervals[intervals.length - 1][1]});
        return res.toArray(new int[res.size()][]);
    }
}

66. Add one (easy)

  • Idea: if digits [i]% = 10 is not 0, it will directly return to digits. If there is no reutrn loss during the cycle, it means that it has been carried to the maximum position.
  • Complexity: time complexity O(n), space complexity O(1)

js:

//Example: 12, 19, 99
var plusOne = function(digits) {
    const len = digits.length;
    for(let i = len - 1; i >= 0; i--) {
        digits[i]++;
        digits[i] %= 10;//Find the remaining 10 to overwrite the current position
        if(digits[i]!=0)//This number is returned directly without carry
            return digits;
    }
    digits = [...Array(len + 1)].map(_=>0);//The loop does not return, and the processing is carried to the maximum position
   //[1,0,0]
    digits[0] = 1;
    return digits;
};

java:

class Solution {
    public int[] plusOne(int[] digits) {
        int len = digits.length;
        for(int i = len - 1; i >= 0; i--) {
            digits[i]++;
            digits[i] %= 10;
            if(digits[i]!=0)
                return digits;
        }
        digits = new int[len + 1];
        digits[0] = 1;
        return digits;
    }
}

73. Matrix zeroing( medium)

  • Idea: mark whether the first row and the first column have 0 with two variables, and then cycle the matrix. If 0 is encountered, mark the elements of the first row and the first column that are the same as this grid as 0. In the cycle matrix, if the first row and the first column corresponding to the current grid are 0, set this cell to 0. Finally, if the first column has 0, set all the first columns to 0. If the second column has 0 If a row has 0, set all the first row to 0
  • Complexity: time complexity O(mn), m and n are the rows and columns of the matrix. Space complexity O(1)

js:

var setZeroes = function(matrix) {
    const m = matrix.length, n = matrix[0].length;
    let flagCol0 = false, flagRow0 = false;//Indicates whether the first row and the first column have 0
    for (let i = 0; i < m; i++) {//Find if the first column exists 0
        if (matrix[i][0] === 0) {
            flagCol0 = true;
        }
    }
    for (let j = 0; j < n; j++) {
        if (matrix[0][j] === 0) {
            flagRow0 = true;
        }
    }
    for (let i = 1; i < m; i++) {//If the circular matrix encounters 0, the elements of the first row and the first column that are the same as this grid are marked as 0
        for (let j = 1; j < n; j++) {
            if (matrix[i][j] === 0) {
                matrix[i][0] = matrix[0][j] = 0;
            }
        }
    }
    for (let i = 1; i < m; i++) {//Circular matrix. If the first row and column corresponding to the current grid are 0, set this cell to 0
        for (let j = 1; j < n; j++) {
            if (matrix[i][0] === 0 || matrix[0][j] === 0) {
                matrix[i][j] = 0;
            }
        }
    }
    if (flagCol0) {//If the first column has 0, set all the first columns to 0
        for (let i = 0; i < m; i++) {
            matrix[i][0] = 0;
        }
    }
    if (flagRow0) {//If the first row has 0, set all the first rows to 0
        for (let j = 0; j < n; j++) {
            matrix[0][j] = 0;
        }
    }
};

java

class Solution {
    public void setZeroes(int[][] matrix) {
        int m = matrix.length, n = matrix[0].length;
        boolean flagCol0 = false, flagRow0 = false;
        for (int i = 0; i < m; i++) {
            if (matrix[i][0] == 0) {
                flagCol0 = true;
            }
        }
        for (int j = 0; j < n; j++) {
            if (matrix[0][j] == 0) {
                flagRow0 = true;
            }
        }
        for (int i = 1; i < m; i++) {
            for (int j = 1; j < n; j++) {
                if (matrix[i][j] == 0) {
                    matrix[i][0] = matrix[0][j] = 0;
                }
            }
        }
        for (int i = 1; i < m; i++) {
            for (int j = 1; j < n; j++) {
                if (matrix[i][0] == 0 || matrix[0][j] == 0) {
                    matrix[i][j] = 0;
                }
            }
        }
        if (flagCol0) {
            for (int i = 0; i < m; i++) {
                matrix[i][0] = 0;
            }
        }
        if (flagRow0) {
            for (int j = 0; j < n; j++) {
                matrix[0][j] = 0;
            }
        }
    }
}

419. Warships on deck (medium)

  • Idea: find the number of bow
  • Complexity: time complexity O(n^2), space complexity O(1)
X..X
...X
...X

js:

function countBattleships(board) {
    const lenX = board.length, lenY = board[0].length
    let count = 0
    for (let i = 0; i < lenX; i++) {
        for (let j = 0; j < lenY; j++) {
            //Not X on the left and above, but bow
            if ((board[i][j] == 'X') && (i == 0 || board[i - 1][j] == '.') && (j == 0 || board[i][j - 1] == '.')) {
                ++count;
            }

        }
    }
    return count
};

java:

class Solution {
    public int countBattleships(char[][] board) {
        int count=0,i,j;
        for(i=0;i<board.length;++i) {
            for(j=0;j<board[0].length;++j){
                if((board[i][j]=='X')&&(i==0||board[i-1][j]=='.')&&(j==0||board[i][j-1]=='.')) {
                    ++count;
                }
            }
        }
        return count;
    }
}

Posted by gary00ie on Mon, 06 Dec 2021 20:58:17 -0800