408算法题leetcode--第28天

84. 柱状图中最大的矩形

题目地址84. 柱状图中最大的矩形 - 力扣(LeetCode)

题解思路:暴力:每一列记为矩形的高,找左边和右边比他小的位置,得到以该列为高对应的宽;这样最大的矩形 = max(每一列为高 * 对应的宽)

优化思路:单调栈,递减栈:暴力中找左右的过程可以进行预处理,单调栈记录某一列左/右第一个比他小的位置;cur指向右边第一个小的位置,stk.top指向该列,stk.top-1指向左边第一个小的位置

时间复杂度:O(n)

空间复杂度:O(n)

代码:

class Solution {
public:
    int largestRectangleArea(vector<int>& heights) {
        int ret = 0; 
        // 前后需要哨兵
        heights.insert(heights.begin(), 0);
        heights.emplace_back(0);
        int size = heights.size();
        stack<int>stk;
        stk.push(0);  // 下标
        for(int i = 1; i < size; i++){
            if(heights[i] >= heights[stk.top()]){
                stk.push(i);
            } else {
                while(!stk.empty() && heights[i] < heights[stk.top()]){
                    int mid = stk.top();
                    stk.pop();
                    if(!stk.empty()){
                        int left = stk.top();
                        int h = heights[mid];
                        int w = i - left - 1;
                        ret = max(ret, h * w);
                    }
                }
                stk.push(i);
            }
        }
        return ret;
    }
};

77. 组合

题目地址77. 组合 - 力扣(LeetCode)

题解思路:如注释

时间复杂度:O( C n k ∗ k C^k_n * k Cnkk),组合数,然后每次记录emplace_back用k

空间复杂度:O(n),递归

代码:

class Solution {
public:
    vector<vector<int>>ret;
    vector<int>path;

    void backtrack(int n, int k, int start){
        if(path.size() == k){
            ret.emplace_back(path);
            return;
        }
        // 剪枝,还需要k - path.size()个元素,即下标从n - (k - size) + 1
        for(int i = start; i <= n - (k - path.size()) + 1; i++){
            path.emplace_back(i);
            backtrack(n, k, i + 1);
            path.pop_back();
        }
    }

    vector<vector<int>> combine(int n, int k) {
        // 回溯,树形结构,从左到右
        // 确定返回类型和参数类型;终止条件;单层逻辑
        backtrack(n, k, 1);
        return ret;
    }
};

216. 组合总和 III

题目地址216. 组合总和 III - 力扣(LeetCode)

题解思路:回溯,如注释

时间复杂度:O( C n k ∗ k C^k_n * k Cnkk),组合数,然后每次记录emplace_back用k

空间复杂度:O(n),递归

代码:

class Solution {
public:
    vector<vector<int>>ret;
    vector<int>path;

    void backtrack(int k, int n, int start, int sum){
        if(path.size() == k){
            if(sum == n){
                ret.push_back(path);
            }
            return ;
        }
        // 剪枝1, sum过大;剪枝2,还需要k - size个数字,下标从9 - (k - size) + 1开始
        if(sum > n){
            return;
        }
        if(start > 9 - (k - path.size()) + 1){
            return ;
        } 
        // 单层
        for(int i = start; i <= 9; i++){
            path.emplace_back(i);
            backtrack(k, n, i + 1, sum + i);
            path.pop_back();
        }
    }

    vector<vector<int>> combinationSum3(int k, int n) {
        backtrack(k, n, 1, 0);
        return ret;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值