[Solutions to LeetCode Algorithm Series] Questions 76~80

LeetCode 76. Minimum covering substring (difficult)

[Title description]

Give you a string s, a string t. Returns the smallest substring scovering tall characters in . If sthere is no tsubstring covering all characters in , an empty string is returned "".

Notice:

  • For trepeated characters in , the number of characters in the substring we are looking for must be no less than tthe number of characters in .
  • If ssuch a substring exists in , we guarantee that it is the only answer.

【Example 1】

输入:s = "ADOBECODEBANC", t = "ABC"
输出:"BANC"
解释:最小覆盖子串 "BANC" 包含来自字符串 t 的 'A'、'B' 和 'C'。

【Example 2】

输入:s = "a", t = "a"
输出:"a"
解释:整个字符串 s 是最小覆盖子串。

【Example 3】

输入: s = "a", t = "aa"
输出: ""
解释: t 中两个字符 'a' 均应包含在 s 的子串中,
因此没有符合条件的子字符串,返回空字符串。

【hint】

1 ≤ s length , t length ≤ 1 0 5 1\and s.length, t.length\and 10^51s.length,t.length105
s andtconsists of English letters

【analyze】


This question is a classic application of sliding windows. We enumerate seach right endpoint ii ini , for eachiiFind the nearest left endpointjj for ij , such thats[j, i]containstall characters in .

Questions that can use sliding windows (double pointers) must be monotonic, that is, when iijjwhile i is moving to the rightj will never move to the left. Assuming thats[j, i]already containstall the characters in , then wheniii moves to the right and becomesi ′ i'i afters[j, i']must also containtall the characters in , sojjIt is impossible for j to move to the lefts[j', i'].

Another question is how to quickly determine whether the current interval contains tall the characters in . We can use a hash table to count tthe number of occurrences of each character in ( t_cnt) and the number of occurrences of each character in the sliding window ( s_cnt), and then use How many characters in a variable cntstatistics tare included in the sliding window? If cntequal to tthe length of , it means that all characters are included. So how to accurately count cnt? Just discuss it on a case-by-case basis:

  • If cthe number of times the current character appears in the sliding window is greater than tthe number of the character in , it will not be accumulated cnt;
  • If cthe number of times the current character appears in the sliding window is less than or equal to tthe number of the character in , then cntone will be added to .

If s[j]the number of occurrences of the character is greater than tthe number of the character in , jj can bej moves to the right.


【Code】

class Solution {
    
    
public:
    string minWindow(string s, string t) {
    
    
        unordered_map<char, int> s_cnt, t_cnt;
        int cnt = 0;
        string res;
        for (auto &c: t) t_cnt[c]++;
        for (int i = 0, j = 0; i < s.size(); i++)
        {
    
    
            s_cnt[s[i]]++;
            if (s_cnt[s[i]] <= t_cnt[s[i]]) cnt++;
            while (s_cnt[s[j]] > t_cnt[s[j]]) s_cnt[s[j]]--, j++;
            if (cnt == t.size() && (res.empty() || i - j + 1 < res.size()))
                res = s.substr(j, i - j + 1);
        }
        return res;
    }
};

LeetCode 77. Combination (medium)

[Title description]

Given two integers nand k, return [1, n]all possible kcombinations of numbers in the range.
You can return answers in any order .

【Example 1】

输入:n = 4, k = 2
输出:
[
  [2,4],
  [3,4],
  [2,3],
  [1,2],
  [1,3],
  [1,4],
]

【Example 2】

输入:n = 1, k = 1
输出:[[1]]

【hint】

1 ≤ n ≤ 20 1\le n\le 201n20
1 ≤ k ≤ n 1\le k\le n1kn

【analyze】


DFS search is enough. You need to pay attention to the heavy judgment. You can specify the search order from small to large, that is, if you have searched iiAfter i, the next number starts fromi + 1 i+1i+1 Start searching.


【Code】

class Solution {
    
    
public:
    vector<vector<int>> res;
    vector<int> v;

    vector<vector<int>> combine(int n, int k) {
    
    
        dfs(n, k, 1);
        return res;
    }

    void dfs(int n, int k, int now)
    {
    
    
        if (!k) {
    
     res.push_back(v); return; }
        for (int i = now; i <= n; i++)
        {
    
    
            v.push_back(i);
            dfs(n, k - 1, i + 1);
            v.pop_back();
        }
    }
};

LeetCode 78. Subset (Medium)

[Title description]

You are given an array of integers with distinctnums elements . Returns all possible subsets (power sets) of this array. The solution set cannot contain duplicate subsets. You can return the solution sets in any order .

【Example 1】

输入:nums = [1,2,3]
输出:[[],[1],[2],[1,2],[3],[1,3],[2,3],[1,2,3]]

【Example 2】

输入:nums = [0]
输出:[[],[0]]

【hint】

1 ≤ n u m s . l e n g t h ≤ 10 1\le nums.length\le 10 1nums.length10
− 10 ≤ nums [ i ] ≤ 10 -10\le nums[i]\le 1010nums[i]
numsAll elements in 10 are different from each other

【analyze】


If you use search to write this question, it is actually the same as the previous question. You only need to enumerate kkthe size of k , then for eachkkJust run DFS on all k , and no code will be given in this way.

Or we can search in another way. For each number, we can choose or not choose. There are two options. Just take both options into consideration when doing DFS.

When we want to enumerate each subset of numbers to choose or not to choose, we can use a binary number to represent it. For example, if we want to enumerate three numbers to choose or not to choose, we can use a three-digit binary number to represent it. When this When the binary number is , 000it means none of the three numbers are selected, when 001it is , it means only the third number is selected, and so on.


【Code】

[DFS implementation code]

class Solution {
    
    
public:
    vector<vector<int>> res;
    vector<int> v;

    vector<vector<int>> subsets(vector<int>& nums) {
    
    
        dfs(nums, 0);
        return res;
    }

    void dfs(vector<int>& nums, int u)
    {
    
    
        if (u == nums.size()) {
    
     res.push_back(v); return; }
        dfs(nums, u + 1);  // 不选nums[u]
        v.push_back(nums[u]);  // 选nums[u]
        dfs(nums, u + 1);
        v.pop_back();
    }
};

[Iterative implementation code]

class Solution {
    
    
public:
    vector<vector<int>> subsets(vector<int>& nums) {
    
    
        vector<vector<int>> res;
        int n = nums.size();
        for (int i = 0; i < 1 << n; i++)
        {
    
    
            vector<int> v;
            for (int j = 0; j < n; j++)
                if (i >> j & 1) v.push_back(nums[j]);
            res.push_back(v);
        }
        return res;
    }
};

LeetCode 79. Word Search (Medium)

[Title description]

Given a m x n2D character grid boardand a string word word. If wordexists in the grid, return true; otherwise, return false.
Words must be formed from letters in adjacent cells in alphabetical order, where "adjacent" cells are those that are adjacent horizontally or vertically. Letters in the same cell are not allowed to be used repeatedly.

【Example 1】

Insert image description here

输入:board = [["A","B","C","E"],["S","F","C","S"],["A","D","E","E"]], word = "ABCCED"
输出:true

【Example 2】

Insert image description here

输入:board = [["A","B","C","E"],["S","F","C","S"],["A","D","E","E"]], word = "SEE"
输出:true

【Example 3】

Insert image description here

输入:board = [["A","B","C","E"],["S","F","C","S"],["A","D","E","E"]], word = "ABCB"
输出:false

【hint】

m = = b o a r d . l e n g t h m == board.length m==board.length
n = = b o a r d [ i ] . l e n g t h n == board[i].length n==board[i].length
1 ≤ m , n ≤ 6 1\le m, n\le 6 1m,n6
1 ≤ word length ≤ 15 1\le word.length\le 151word.length15
board andwordconsist only of uppercase and lowercase English letters

【analyze】



【Code】


Guess you like

Origin blog.csdn.net/m0_51755720/article/details/133497088