leetcode(76-80)

本文精选LeetCode上的经典算法题目进行深入解析,包括最小覆盖子串、组合、子集、单词搜索、删除排序数组中的重复项等,涵盖滑动窗口、回溯、DFS等算法技巧。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

76. 最小覆盖子串

给定一个字符串 S 和一个字符串 T,请在 S 中找出包含 T 所有字母的最小子串。

示例:

输入: S = "ADOBECODEBANC", T = "ABC"
输出: "BANC"

说明:

  • 如果 S 中不存这样的子串,则返回空字符串 ""
  • 如果 S 中存在这样的子串,我们保证它是唯一的答案。
class Solution {
public:
    string minWindow(string s, string t) {
        if(t.size() > s.size()) return "";
        string res = "";
        int left=0, count=0, minLen=s.size()+1;
        unordered_map<char,int> m;
        
        for(int i=0; i<t.size(); i++){
            if(m.find(t[i]) != m.end()) m[t[i]]++;
            else m[t[i]] = 1;
        }
        
        for(int right=0; right<s.size(); right++){
            if(m.find(s[right]) != m.end()){
                --m[s[right]];
                if(m[s[right]] >= 0) count++;
                while(count == t.size()){
                    if(right-left+1 < minLen){
                        minLen = right-left+1;
                        res = s.substr(left, minLen);
                    }
                    if(m.find(s[left]) != m.end()){
                        m[s[left]]++;
                        if(m[s[left]] > 0) count--;
                    }
                    left++;
                }
            }
        }
        return res;
    }
};

77.组合

给定两个整数 n 和 k,返回 1 ... 中所有可能的 k 个数的组合。

示例:

输入: n = 4, k = 2
输出:
[
  [2,4],
  [3,4],
  [2,3],
  [1,2],
  [1,3],
  [1,4],
]
class Solution {
public:
    vector<vector<int>> combine(int n, int k) {
        vector<vector<int>> res;
        if(n<k) return res;
        vector<int> nums;
        comb(n,k,1,nums,res);
        return res;
    }
    
    void comb(int n, int k, int start, vector<int> nums, vector<vector<int>>& res){
        if(k == nums.size()){
            res.push_back(nums);
            return;
        }
        for(int i=start; i <= n-(k-nums.size())+1; i++){
            nums.push_back(i);
            comb(n,k,i+1,nums,res);
            nums.pop_back();
        }
    }
};

78. 子集

给定一组不含重复元素的整数数组 nums,返回该数组所有可能的子集(幂集)。

说明:解集不能包含重复的子集。

示例:

输入: nums = [1,2,3]
输出:
[
  [3],
  [1],
  [2],
  [1,2,3],
  [1,3],
  [2,3],
  [1,2],
  []
]
class Solution {
public:
    vector<vector<int>> subsets(vector<int>& nums) {
        vector<vector<int>> res;
        sort(nums.begin(), nums.end());
        int n = nums.size();
        vector<int> tmp;
        for(int i=0; i<pow(2,n); i++){
            for(int j=0; j<n; j++){
                if(i & 1 << j) tmp.push_back(nums[j]);
            }
            res.push_back(tmp);
            tmp.clear();
        }
        return res;
    }   
};

79. 单词搜索

给定一个二维网格和一个单词,找出该单词是否存在于网格中。

单词必须按照字母顺序,通过相邻的单元格内的字母构成,其中“相邻”单元格是那些水平相邻或垂直相邻的单元格。同一个单元格内的字母不允许被重复使用。

示例:

board =
[
  ['A','B','C','E'],
  ['S','F','C','S'],
  ['A','D','E','E']
]

给定 word = "ABCCED", 返回 true.
给定 word = "SEE", 返回 true.
给定 word = "ABCB", 返回 false.
class Solution {
public:
    bool exist(vector<vector<char>>& board, string word) {
        if(board.empty()) return false;
        int row = board.size();
        int col = board[0].size();
        vector<vector<bool>> visited(row, vector<bool>(col,false));
        for(int i=0; i<row; i++){
            for(int j=0; j<col; j++){
                if(dfs(board, word, 0, i, j, visited)) return true;
            }
        }
        return false;
    }
    bool dfs(vector<vector<char>> &board, string &word,int index, int i, int j, vector<vector<bool>> &visited){
        if(index == word.size()) return true;
        if(i<0 || j<0 || i>=board.size() || j>=board[0].size()) return false;
        if(visited[i][j]) return false;
        if(word[index] != board[i][j]) return false;
        visited[i][j] = true;
        bool res = dfs(board, word, index+1, i-1, j, visited) ||
                   dfs(board, word, index+1, i+1, j, visited) ||
                   dfs(board, word, index+1, i, j-1, visited) ||
                   dfs(board, word, index+1, i, j+1, visited);
        visited[i][j] = false;
        return res;
    }
};

80. 删除排序数组中的重复项 II

给定一个排序数组,你需要在原地删除重复出现的元素,使得每个元素最多出现两次,返回移除后数组的新长度。

不要使用额外的数组空间,你必须在原地修改输入数组并在使用 O(1) 额外空间的条件下完成。

示例 1:

给定 nums = [1,1,1,2,2,3],

函数应返回新长度 length = 5, 并且原数组的前五个元素被修改为 1, 1, 2, 2,3

你不需要考虑数组中超出新长度后面的元素。

示例 2:

给定 nums = [0,0,1,1,1,1,2,3,3],

函数应返回新长度 length = 7, 并且原数组的前五个元素被修改为 0, 0, 1, 1, 2, 3, 3 。

你不需要考虑数组中超出新长度后面的元素。
class Solution {
public:
    int removeDuplicates(vector<int>& nums) {
        if(nums.size() == 0) return 0;
        else if(nums.size() == 1) return 1;
        int pos = 0;
        int flag = 0;
        for(int i=1; i<nums.size(); i++){
            if(nums[i] != nums[pos]) {
                nums[++pos] = nums[i];
                flag = 0;
            } else if(nums[i] == nums[pos] && !flag){
                nums[++pos] = nums[i];
                flag = 1;
            } else {
                
            }
        }
        return ++pos;
    }
};

(以上题目均摘自leetcode)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值