LeetCode题号300+

309. 最佳买卖股票时机含冷冻期

给定一个整数数组,其中第 i 个元素代表了第 i 天的股票价格 。

设计一个算法计算出最大利润。在满足以下约束条件下,你可以尽可能地完成更多的交易(多次买卖一支股票):

你不能同时参与多笔交易(你必须在再次购买前出售掉之前的股票)。
卖出股票后,你无法在第二天买入股票 (即冷冻期为 1 天)。

思路

  • dp,由于每次只用数组的前一个值,所以可以优化一下空间复杂度
class Solution {
public:
    int maxProfit(vector<int>& prices) {
        if (!prices.size()) {
            return 0;
        }
        int dp[prices.size()][3];// 0手中有股票,1封闭期,2没封闭
        dp[0][0] = -prices[0];
        dp[0][1] = dp[0][2] = 0;
        for (int i = 1;i < prices.size();i++) {
            dp[i][0] = max(dp[i-1][0],dp[i-1][2] - prices[i]);
            dp[i][1] = dp[i-1][0] + prices[i];
            dp[i][2] = max(dp[i-1][1],dp[i-1][2]);
        }
        return max(dp[prices.size()-1][2],dp[prices.size()-1][1]);
    }
};

322. 零钱兑换

给定不同面额的硬币 coins 和一个总金额 amount。编写一个函数来计算可以凑成总金额所需的最少的硬币个数。如果没有任何一种硬币组合能组成总金额,返回 -1。

你可以认为每种硬币的数量是无限的。

思路

  • dp
class Solution {
public:
    int coinChange(vector<int>& coins, int amount) {
        int dp[amount+10];
        memset(dp,0x3f,sizeof(dp));
        dp[0] = 0;
        for (int i = 1;i <= amount;i++) {
            for (int j = 0;j < coins.size();j++) {
                if (i >= coins[j]) dp[i] = min(dp[i],dp[i-coins[j]]+1);
            }
        }
        return dp[amount] == 0x3f3f3f3f ? -1 : dp[amount];
    }   
};

337. 打家劫舍 III

在上次打劫完一条街道之后和一圈房屋后,小偷又发现了一个新的可行窃的地区。这个地区只有一个入口,我们称之为“根”。 除了“根”之外,每栋房子有且只有一个“父“房子与之相连。一番侦察之后,聪明的小偷意识到“这个地方的所有房屋的排列类似于一棵二叉树”。 如果两个直接相连的房子在同一天晚上被打劫,房屋将自动报警。

计算在不触动警报的情况下,小偷一晚能够盗取的最高金额。

思路

  • 选择当前点时,不选择左右节点
  • 不选择当前点时,取左右子树的最大值
class Solution {
public:
    unordered_map<TreeNode*,int> f,g;// f 选择当前节点,g 不选择
    void back(TreeNode* root) {
        if (root == NULL) {
            return ;
        }
        back(root->left);
        back(root->right);
        f[root] = root->val + g[root->left] + g[root->right];
        g[root] = max(f[root->left],g[root->left]) + max(f[root->right],g[root->right]);
    }

    int rob(TreeNode* root) {
        back(root);
        return max(f[root],g[root]);
    }
};

338. 比特位计数

给定一个非负整数 num。对于 0 ≤ i ≤ num 范围中的每个数字 i ,计算其二进制数中的 1 的数目并将它们作为数组返回。

思路

  • 对于任意一个正整数,其结果是将二进制位最后一个1置为0的结果+1
class Solution {
public:
    vector<int> countBits(int num) {
        vector<int> dp;
        dp.push_back(0);
        for (int i = 1;i <= num;i++) {
            dp.push_back(dp[i&(i-1)]+1);
        }
        return dp;
    }
};

347. 前 K 个高频元素

给定一个非空的整数数组,返回其中出现频率前 *k* 高的元素。

思路

  • 计算出每个元素的出现次数,然后问题就变成了返回出现次数前k高的元素了
  • 这时候可以用堆的形式
class Solution {
public:
    static bool cmp(pair<int,int> x,pair<int,int> y) {
        return x.second > y.second;
    }
    vector<int> topKFrequent(vector<int>& nums, int k) {
        unordered_map<int,int> mp;
        priority_queue<pair<int,int>,vector<pair<int,int>>,decltype(&cmp)> q(cmp);
        vector<int> ans;
        for (int i = 0;i < nums.size();i++) {
            mp[nums[i]]++;
        }
        for (auto value : mp) {
            if (q.size() < k) {
                q.push(value);
            } else if (q.top().second < value.second) {
                q.pop();
                q.push(value);
            }
        }
        while (!q.empty()) {
            ans.push_back(q.top().first);
            q.pop();
        }
        return ans;
    }
};

739. 每日温度

请根据每日 气温 列表,重新生成一个列表。对应位置的输出为:要想观测到更高的气温,至少需要等待的天数。如果气温在这之后都不会升高,请在该位置用 0 来代替。

例如,给定一个列表 temperatures = [73, 74, 75, 71, 69, 72, 76, 73],你的输出应该是 [1, 1, 4, 2, 1, 1, 0, 0]

提示:气温 列表长度的范围是 [1, 30000]。每个气温的值的均为华氏度,都是在 [30, 100] 范围内的整数。

思路

  • 温度范围[30,100],先遍历温度列表,再遍历[x,100]

  • class Solution {
    public:
        vector<int> dailyTemperatures(vector<int>& T) {
            vector<int> ans;
            queue<int> q[101];
            for (int i = 0;i < T.size();i++) {
                q[T[i]].push(i);
            }
            for (int i = 0;i < T.size();i++) {
                int index = T.size();
                for (int j = T[i]+1;j <= 100;j++) {
                    if (!q[j].empty()) {
                        index = min(q[j].front(),index);
                    }
                }
                q[T[i]].pop();
                ans.push_back(index == T.size() ? 0 : index-i );
            }
            return ans;
        }
    };
    
  • 单调栈,让栈单调递减

  • class Solution {
    public:
        vector<int> dailyTemperatures(vector<int>& T) {
            vector<int> ans(T.size());
            stack<int> s;
            for (int i = 0;i <= T.size();i++) {
                while (!s.empty() && (i == T.size() || T[s.top()] < T[i])) {
                    ans[s.top()] = (i == T.size() ? 0 : i - s.top());
                    s.pop();
                }
                s.push(i);
            }
            return ans;
        }
    };
    
原文地址:https://www.cnblogs.com/MMMMMMMW/p/13961635.html