前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >【LeetCode 热题 100】滑动窗口最大值 / 最小覆盖子串 / 轮转数组 / 缺失的第一个正数

【LeetCode 热题 100】滑动窗口最大值 / 最小覆盖子串 / 轮转数组 / 缺失的第一个正数

作者头像
_小羊_
发布于 2025-04-26 11:41:07
发布于 2025-04-26 11:41:07
8900
代码可运行
举报
文章被收录于专栏:C++C++
运行总次数:0
代码可运行

子串

和为 K 的子数组
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
class Solution {
public:
    int subarraySum(vector<int>& nums, int k) {
        unordered_map<int, int> hash;
        hash[0] = 1;
        int pre = 0, res = 0;
        for (auto e : nums)
        {
            pre += e;
            res += hash[pre - k];
            hash[pre]++;
        }
        return res;
    }
};

滑动窗口最大值

看完这个题很容易想到用优先级队列,但是我写了一半突然意识到,当左侧出窗口时优先级队列好像无法立马找到这个值并删除,所以就放弃了这个想法; 于是就又想到set也能排序,通过 rbegin() 返回最大值对应的迭代器,但是数组中可能会出现重复的数,而set会去重,所以就又想到 multiset,它可以真正意义上的排序。 但是测试了一下发现AC不了,又想到 multiset 虽然不去重,但是 erase 会把所有相同的值都删除,所以这个办法好像又不行; 但是又突然想到之前学习 multiset 的时候测试过不同的 erase 删除,发现传值、传迭代器、传迭代器区间,最后的结果是不同的。其中传值和传迭代器区间会把所有相同的值都删除,而传迭代器的话只会删除一个。 于是又测试了一下,终于过了。但是N*logN的时间负责度居然才击败了百分之5的用户🤡

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
class Solution {
public:
    vector<int> maxSlidingWindow(vector<int>& nums, int k) {
        vector<int> res;
        multiset<int> hash;
        for (int l = 0, r = 0; r < nums.size(); r++) 
        {
            hash.insert(nums[r]);
            if (r - l + 1 == k)
            {
                res.push_back(*hash.rbegin());
                hash.erase(hash.find(nums[l++]));
            }
        }
        return res;
    }
};

这位兄弟在官方题解下大彻大悟,我要是有他一半悟性就好了哈哈…

下面是看了官解才学到的方法,对嘛,用键值对绑定起来不就能找到了。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
class Solution {
public:
    vector<int> maxSlidingWindow(vector<int>& nums, int k) {
        vector<int> res;
        priority_queue<pair<int, int>> pq;
        for (int i = 0; i < k; i++)
        {
            pq.emplace(nums[i], i);
        }
        res.push_back(pq.top().first);
        for (int i = k; i < nums.size(); i++)
        {
            pq.emplace(nums[i], i);
            while (pq.top().second <= i - k) // 关键 <=
            {
                pq.pop();
            } 
            res.push_back(pq.top().first);
        } 
        return res;
    }
};

最小覆盖子串
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
class Solution {
public:
    string minWindow(string s, string t) {
        int hash1[128] = {};
        int m = s.size(), n = t.size();
        for (auto ch : t) hash1[ch - 'A']++;
        int hash2[128] = {};
        int begin = 0, len = m + 1;
        for (int l = 0, r = 0, cnt = 0; r < m; r++)
        {
            int in = s[r] - 'A';
            if (++hash2[in] <= hash1[in]) cnt++;
            while (cnt == n)
            {
                if (r - l + 1 < len)
                {
                    len = r - l + 1;
                    begin = l;
                }
                int out = s[l++] - 'A';
                if (hash2[out]-- <= hash1[out]) cnt--;
            }
        }
        return len > m ? "" : s.substr(begin, len);
    }
};

普通数组

最大子数组和

定义 dp[i] 表示以i位置为结尾的最大子数组,则以i位置为结尾的子数组可以分为两类:i位置元素单独构成子数组,i位置及其之前所有元素构成子数组,则可得状态转移方程:dp[i] = max(dp[i - 1] + nums[i], nums[i]);

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
class Solution {
public:
    int maxSubArray(vector<int>& nums) {
        int res = -0x3f3f3f3f;
        int n = nums.size();
        vector<int> dp(n + 1);
        for (int i = 1; i <= n; i++)
        {
            dp[i] = max(dp[i - 1] + nums[i - 1], nums[i - 1]);
            res = max(res, dp[i]);
        }
        return res;
    }
};

空间优化。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
class Solution {
public:
    int maxSubArray(vector<int>& nums) {
        int res = -0x3f3f3f3f;
        int pre = 0;
        for (auto e : nums)
        {
            pre = max(pre, 0) + e;
            res = max(res, pre);
        }
        return res;
    }
};

这就是我算法不好的原因吗?


合并区间

一道区间贪心问题。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
class Solution {
public:
    vector<vector<int>> merge(vector<vector<int>>& intervals) {
        sort(intervals.begin(), intervals.end());
        vector<vector<int>> res;
        int l = intervals[0][0], r = intervals[0][1];
        for (int i = 1; i < intervals.size(); i++)
        {
            int a = intervals[i][0], b = intervals[i][1];
            // 当区间重叠时合并两个区间
            if (a <= r) r = max(r, b);
            else 
            {
                // 当区间不重叠时插入
                res.push_back({l, r});
                l = a, r = b;
            }
        }
        res.push_back({l, r});
        return res;
    }
};

轮转数组

本题解法:爱滴魔力转圈圈。 我们来观察结果,原数组右边某个区间长度的数都平移到了左边,左边剩余区间长度的数都平移到了右边。那我们把数组反转就可以得到类似的效果,但是此时两部分都是反转的,那我们再对应区间反转即可。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
class Solution {
public:
    void rotate(vector<int>& nums, int k) {
        k %= nums.size();
        reverse(nums.begin(), nums.end());
        reverse(nums.begin(), nums.begin() + k);
        reverse(nums.begin() + k, nums.end());
    }
};

除自身以外数组的乘积
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
class Solution {
public:
    vector<int> productExceptSelf(vector<int>& nums) {
        int n = nums.size(); 
        vector<int> f(n, 1), g(n, 1), res(n);
        for (int i = 1; i < n; i++) f[i] = f[i - 1] * nums[i - 1];
        for (int i = n - 2; i >= 0; i--) g[i] = g[i + 1] * nums[i + 1];
        for (int i = 0; i < n; i++) res[i] = f[i] * g[i];
        return res;
    }
};

缺失的第一个正数

这题做的跟吃了蟑螂一样难受。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
class Solution {
public:
    int firstMissingPositive(vector<int>& nums) {
        int n = nums.size();
        for (int i = 0; i < n; i++)
        {
            while (nums[i] > 0 && nums[i] <= n && nums[nums[i] - 1] != nums[i])
            {
                swap(nums[nums[i] - 1], nums[i]);
            }
        }
        for (int i = 0; i < n; i++)
        {
            if (nums[i] != i + 1)
            {
                return i + 1;
            }
        }
        return n + 1;
    }
};

本篇文章的分享就到这里了,如果您觉得在本文有所收获,还请留下您的三连支持哦~

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2025-04-25,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 子串
    • 和为 K 的子数组
    • 滑动窗口最大值
    • 最小覆盖子串
  • 普通数组
    • 最大子数组和
    • 合并区间
    • 轮转数组
    • 除自身以外数组的乘积
    • 缺失的第一个正数
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档