【LeetCode 热题 100】有效的括号 / 最小栈 / 字符串解码 / 柱状图中最大的矩形

⭐️个人主页:@小羊 ⭐️所属专栏:LeetCode 热题 100 很荣幸您能阅读我的文章,诚请评论指点,欢迎欢迎 ~

目录


有效的括号

cpp 复制代码
class Solution {
public:
    bool isValid(string s) {
        stack<char> st;
        for (char e : s)
        {
            if (st.empty()) st.push(e);
            else if (st.top() == '(' && e == ')' || st.top() == '{' && e == '}'
                || st.top() == '[' && e == ']') st.pop();
            else st.push(e);
        }
        return st.empty();
    }
};

最小栈

cpp 复制代码
class MinStack {
    stack<int> st;
    stack<int> minst;
public:
    MinStack() {
        
    }
    
    void push(int val) {
        st.push(val);
        if (minst.empty() || val <= minst.top())
        {
            minst.push(val);
        }
    }
    
    void pop() {
        if (st.top() == minst.top())
        {
            minst.pop();
        }
        st.pop();
    }
    
    int top() {
        return st.top();
    }
    
    int getMin() {
        return minst.top();
    }
};

字符串解码

cpp 复制代码
class Solution {
public:
    string decodeString(string s) {
        int i = 0;
        return dfs(s, i);
    }
    string dfs(const string& s, int& i)
    {
        string str;
        while (i < s.size() && s[i] != ']')
        {
            if (isdigit(s[i]))
            {
                int num = 0;
                while (i < s.size() && s[i] != '[')
                {
                    num = num * 10 + s[i++] - '0';
                }
                i++; // 跳过'['
                string tmp = dfs(s, i);
                i++; // 跳过']'
                while (num--) str += tmp;
            }
            else str += s[i++];
        }
        return str;
    }
};

每日温度

cpp 复制代码
class Solution {
public:
    vector<int> dailyTemperatures(vector<int>& temperatures) {
        int n = temperatures.size();
        stack<int> st;
        vector<int> res(n);
        for (int i = 0; i < n; i++)
        {
            while (st.size() && temperatures[st.top()] < temperatures[i])
            {
                int t = st.top();
                st.pop();
                res[t] = i - t;
            }
            st.push(i);
        }
        return res;
    }
};

柱状图中最大的矩形

  1. 单调递增栈:分别从左向右和从右向左遍历,找到每个柱子左边和右边第一个比它矮的柱子位置。
  2. 计算宽度:对于每个柱子,其左右边界之间的距离即为矩形的宽度,高度为当前柱子的高度。
  3. 求最大值:遍历所有可能的矩形,找出面积最大的一个。
    单调栈。
cpp 复制代码
class Solution {
public:
    int largestRectangleArea(vector<int>& heights) {
        int n = heights.size();
        vector<int> left(n), right(n);
        stack<int> st;
        for (int i = 0; i < n; i++)
        {
            while (st.size() && heights[st.top()] >= heights[i])
            {
                st.pop();
            }
            left[i] = st.empty() ? -1 : st.top();
            st.push(i);
        }
        st = stack<int>();
        for (int i = n - 1; i >= 0; i--)
        {
            while (st.size() && heights[st.top()] >= heights[i])
            {
                st.pop();
            }
            right[i] = st.empty() ? n : st.top();
            st.push(i);
        }
        int res = 0;
        for (int i = 0; i < n; i++)
        {
            res = max(res, (right[i] - left[i] - 1) * heights[i]);
        }
        return res;
    }
};

优化。

cpp 复制代码
class Solution {
public:
    int largestRectangleArea(vector<int>& heights) {
        int n = heights.size();
        vector<int> left(n, -1), right(n, n);
        stack<int> st;
        for (int i = 0; i < n; i++)
        {
            while (st.size() && heights[st.top()] > heights[i])
            {
                right[st.top()] = i;
                st.pop();
            }
            if (st.size()) left[i] = st.top(); 
            st.push(i);
        }
        int res = 0;
        for (int i = 0; i < n; i++)
        {
            res = max(res, (right[i] - left[i] - 1) * heights[i]);
        }
        return res;
    }
};

数组中的第K个最大元素

建堆。

cpp 复制代码
class Solution {
public:
    int findKthLargest(vector<int>& nums, int k) {
        int n = nums.size();
        for (int i = n - 2 / 2; i >= 0; i--)
        {
            adjust_down(nums, i, n);
        }
        while (--k)
        {
            swap(nums[0], nums[--n]);
            adjust_down(nums, 0, n);
        }
        return nums[0];
    }
    void adjust_down(vector<int>& nums, int parent, int n)
    {
        int child = 2 * parent + 1;
        while (child < n) 
        {
            if (child + 1 < n && nums[child + 1] > nums[child]) child++;
            if (nums[child] > nums[parent])
            {
                swap(nums[child], nums[parent]);
                parent = child;
                child = 2 * parent + 1;
            }
            else break;
        }
    }
};

快速选择。

cpp 复制代码
class Solution {
public:
    int findKthLargest(vector<int>& nums, int k) {
        srand(time(nullptr));
        return qsort(nums, 0, nums.size() - 1, k);
    }
    int qsort(vector<int>& nums, int l, int r, int k)
    {
        if (l >= r) return nums[l];
        int key = nums[rand() % (r - l + 1) + l];
        int i = l, left = l - 1, right = r + 1;
        while (i < right) 
        {
            if (nums[i] < key) swap(nums[++left], nums[i++]);
            else if (nums[i] == key) i++;
            else swap(nums[--right], nums[i]);
        }
        int x = r - right + 1, y = right - left - 1;
        if (x >= k) return qsort(nums, right, r, k);
        else if (x + y >= k) return key;
        else return qsort(nums, l, left, k - x - y);
    }
};

前 K 个高频元素

建小堆,找出前K的最大的。

cpp 复制代码
class Solution {
    using pii = pair<int, int>;
    struct cmp{
        bool operator()(const pii& p1, const pii& p2)
        {
            return p1.second > p2.second;
        }
    };
public:
    vector<int> topKFrequent(vector<int>& nums, int k) {
        unordered_map<int, int> hashmap;
        for (auto e : nums) hashmap[e]++;
        priority_queue<pii, vector<pii>, cmp> pq;
        for (auto& [a, b] : hashmap)
        {
            if (pq.size() == k)
            {
                if (b > pq.top().second)
                {
                    pq.pop();
                    pq.emplace(a, b);
                }
            } 
            else pq.emplace(a, b);
        }
        vector<int> res;
        while (pq.size())
        {
            res.push_back(pq.top().first);
            pq.pop();
        }
        return res;
    }
};

数据流的中位数

cpp 复制代码
class MedianFinder {
    priority_queue<int> left;
    priority_queue<int, vector<int>, greater<int>> right;
public:
    MedianFinder() {
        
    }
    
    void addNum(int num) {
        if (left.size() == right.size())
        {
            if (left.size() && num <= left.top()) left.push(num);
            else 
            {
                right.push(num);
                left.push(right.top());
                right.pop();
            }
        }
        else{
            if (num >= left.top()) right.push(num);
            else{
                left.push(num);
                right.push(left.top());
                left.pop();
            }
        }
    }
    
    double findMedian() {
        if (left.size() == right.size()) return (left.top() + right.top()) / 2.0;
        else return left.top();
    }
};

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

相关推荐
爱coding的橙子几秒前
每日算法刷题计划day13 5.22:leetcode不定长滑动窗口最短/最小1道题+求子数组个数越长越合法2道题,用时1h
算法·leetcode·职场和发展
编程绿豆侠几秒前
力扣HOT100之二叉树: 437. 路径总和 III
算法·leetcode·哈希算法
范纹杉想快点毕业31 分钟前
Google C++ Style Guide 谷歌 C++编码风格指南,深入理解华为与谷歌的编程规范——C和C++实践指南
c语言·数据结构·c++·qt·算法
烨然若神人~1 小时前
算法第26天 | 贪心算法、455.分发饼干、376. 摆动序列、 53. 最大子序和
算法·贪心算法
信奥洪老师1 小时前
2025年 全国青少年信息素养大赛 算法创意挑战赛C++ 小学组 初赛真题
c++·算法·青少年编程·等级考试
学习使我变快乐1 小时前
C++:关联容器set容器,multiset容器
开发语言·c++·算法
z人间防沉迷k1 小时前
高效查询:位图、B+树
开发语言·数据结构·笔记·python·算法
geneculture3 小时前
《黄帝内经》数学建模与形式化表征方式的重构
人工智能·算法·机器学习·数学建模·重构·课程设计·融智学的重要应用
Vic101013 小时前
GaussDB(PostgreSQL)查询执行计划参数解析技术文档
算法·哈希算法·gaussdb
小喵要摸鱼4 小时前
【软考向】Chapter 3 数据结构
数据结构·算法·排序算法