LeetCode 524. Match the longest word in the dictionary by deleting letters (dynamic programming) / 695. Maximum area of islands / 54. Spiral matrix (back)

Keywords: Java leetcode

524. Match the longest word in the dictionary by deleting letters

One question per day on September 14, 2021

Title Description

Give you a string s and a string array dictionary as a dictionary, find and return the longest string in the dictionary, which can be obtained by deleting some characters in S.

If there is more than one answer, the string with the longest length and the smallest dictionary order is returned. If the answer does not exist, an empty string is returned.

Example 1:

Input: s = "abpcplea", dictionary = ["ale", "apple", "monkey", "plea"]
Output: "apple"

Example 2:

Input: s = "abpcplea", dictionary = ["a", "b", "c"]
Output: "a"

Tips:

1 <= s.length <= 1000
1 <= dictionary.length <= 1000
1 <= dictionary[i].length <= 1000
s and dictionary[i] consist of lowercase letters only

Source: LeetCode
Link: https://leetcode-cn.com/problems/longest-word-in-dictionary-through-deleting
The copyright belongs to Lingkou network. For commercial reprint, please contact the official authorization, and for non-commercial reprint, please indicate the source.

thinking

The length is in descending order, the length is the same, in dictionary order, and then double pointers

class Solution {
    public String findLongestWord(String s, List<String> dictionary) {
        int l = s.length();
        int n = dictionary.size();
        //In descending order of length, the first string found directly can be returned, with the same length and arranged in dictionary order
        Collections.sort(dictionary, (a, b) -> (a.length() == b.length() ? a.compareTo(b) : b.length() - a.length()));
        
        for(int i = 0; i < n; i++){
            String ss = dictionary.get(i);
            int m = ss.length();
            if(m > l)
                continue;
            int idx1 = 0;
            int idx2 = 0;
            while(idx1 < l && idx2 < m){
                if(s.charAt(idx1) == ss.charAt(idx2)){
                    idx1++;
                    idx2++;
                }else{
                    idx1++;
                }
            }
            if(idx2 == m)
                return ss;
        }
        return "";
    }
}

In fact, it is easy to have another idea, that is, preprocessing the string s. if you can quickly find the character at the next position, it will speed up the processing speed
So I learned this dynamic programming
f[i][j] indicates that the subscript of the first j character can be obtained at position i

class Solution {
    public String findLongestWord(String s, List<String> dictionary) {
        int l = s.length();
        int n = dictionary.size();
        //Dynamic gauge, which processes the subscript of other characters after each position for the first time
        int[][] f = new int[l + 1][26];
        //Initialization, it is impossible to get all characters in the last position
        Arrays.fill(f[l], l);
        for(int i = l - 1; i >= 0; i--){
            for(int j = 0; j < 26; j++){
                if(s.charAt(i) == j + 'a'){
                    f[i][j] = i;
                }else{
                    f[i][j] = f[i + 1][j];
                }
            }
        }

        String res = "";
        for(String t : dictionary){
            int idx = 0;
            boolean flag = true;
            for(int i = 0; i < t.length(); i++){
                char c = t.charAt(i);
                if(f[idx][c - 'a'] == l){
                    flag = false;
                    break;
                }
                idx = f[idx][c - 'a'] + 1;
            }
            if(flag){
                if(t.length() > res.length() || (t.length() == res.length() && t.compareTo(res) < 0))
                    res = t;
            }
        }
        return res;

    }
}

695. Maximum area of the island

Today, I did the written test of station B. Although the match code system is still very poor, I didn't write the largest island rotation matrix correctly??? I want to give up for a moment

Title Description

Given a non empty two-dimensional array grid containing some 0 and 1.

An island is a combination of some adjacent 1s (representing land). The "adjacent" here requires that two 1s must be adjacent horizontally or vertically. You can assume that the four edges of the grid are surrounded by 0 (representing 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.

Source: LeetCode
Link: https://leetcode-cn.com/problems/max-area-of-island
The copyright belongs to Lingkou network. For commercial reprint, please contact the official authorization, and for non-commercial reprint, please indicate the source.

thinking

class Solution {
    int m;
    int n;
    int[][] g;
    int max;
    int[][] dir = {{0,1},{0,-1},{1,0},{-1,0}};
    public int maxAreaOfIsland(int[][] grid) {
        m = grid.length;
        n = grid[0].length;
        g = grid;
        for(int i = 0; i < m; i++){
            for(int j = 0; j < n; j++){
                if(g[i][j] == 1){
                    max = Math.max(max, dfs(i, j));
                }
            }
        }
        return max;
    }

    public int dfs(int i, int j){
        if(i < 0 || j < 0 || i >= m || j >= n){
            return 0;
        }
        if(g[i][j] == 0)
            return 0;
        int res = 0;
        g[i][j] = 0;
        for(int t = 0; t < 4; t++){
            int x = i + dir[t][0];
            int y = j + dir[t][1];
            res += dfs(x, y);
        }
        return res + 1;
    }
}

And check the collection to review:

class Solution {

    public int maxAreaOfIsland(int[][] grid) {
        int m = grid.length;
        int n = grid[0].length;
        UnionFind uf = new UnionFind(m * n);
        boolean flag = false;
        for(int i = 0; i < m; i++){
            for(int j = 0; j < n; j++){
                //Merge with the one above the left, because if there is a point, it is 1, it will not be merged, so it needs special judgment
                if(grid[i][j] == 1){
                    flag = true;
                    if(i > 0 && grid[i - 1][j] == 1)
                        uf.union(i * n + j, (i - 1) * n + j);
                    if(j > 0 && grid[i][j - 1] == 1)
                        uf.union(i * n + j, i * n + j - 1);
                }
            }
        }
        if(flag)
            return uf.getmax() > 0 ? uf.getmax() : 1;
        else
            return 0;
    }

}

class UnionFind{
    int[] parents;
    int[] rank;
    int n;
    int[] size;
    int count;
    int max;
    public UnionFind(int n){
        this.n = n;
        parents = new int[n];
        rank = new int[n];
        size = new int[n];
        count = n;
        max = 0;
        for(int i = 0; i < n; i++){
            parents[i] = i;
            size[i] = 1;
            rank[i] = 1;
        }
    }

    public void union(int x, int y){
        int px = find(x);
        int py = find(y);
        if(px == py)
            return;
        if(rank[px] == rank[py]){
            parents[px] = py;
            rank[py]++;
            size[py] += size[px];
            max = Math.max(max, size[py]);
            return;
        }
        if(rank[px] > rank[py]){
            int temp = px;
            px = py;
            py = temp;
        }
        parents[px] = py;
        size[py] += size[px];
        max = Math.max(max, size[py]);
    }

    public int find(int x){
        if(parents[x] != x){
            parents[x] = find(parents[x]);
        }
        return parents[x];
    }

    public int getConnection(){
        return count;
    }

    public int getmax(){
        return max;
    }
}

54. Spiral matrix

Title Description

Give you a matrix with m rows and n columns. Please return all the elements in the matrix in a clockwise spiral order.

Example 1:


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

Example 2:


Input: matrix = [[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]

Tips:

m == matrix.length
n == matrix[i].length
1 <= m, n <= 10
-100 <= matrix[i][j] <= 100

Source: LeetCode
Link: https://leetcode-cn.com/problems/spiral-matrix
The copyright belongs to Lingkou network. For commercial reprint, please contact the official authorization, and for non-commercial reprint, please indicate the source.

thinking

Write this spiral matrix by heart!!!!

class Solution {
    public List<Integer> spiralOrder(int[][] matrix) {
        List<Integer> res = new ArrayList<>();
        int m = matrix.length;
        int n = matrix[0].length;
        //Define four directions
        int left = 0;
        int right = n - 1;
        int up = 0;
        int bottom = m - 1;
        //Total number
        int count = m * n;
        while(count >= 1){
            for(int i = left; i <= right && count >= 1; i++){
                res.add(matrix[up][i]);
                count--;
            }
            up++;
            for(int i = up; i <= bottom && count >= 1; i++){
                res.add(matrix[i][right]);
                count--;
            }
            right--;
            for(int i = right; i >= left && count >= 1; i--){
                res.add(matrix[bottom][i]);
                count--;
            }
            bottom--;
            for(int i = bottom; i >= up && count >= 1; i--){
                res.add(matrix[i][left]);
                count--;
            }
            left++;
        }
        return res;
    }
}

Posted by Benjamin on Thu, 18 Nov 2021 22:26:22 -0800