leetcode解题思路分析(五十九)502 - 508 题

  1. IPO
    给定若干个项目。对于每个项目 i,它都有一个纯利润 Pi,并且需要最小的资本 Ci 来启动相应的项目。最初,你有 W 资本。当你完成一个项目时,你将获得纯利润,且利润将被添加到你的总资本中。总而言之,从给定项目中选择最多 k 个不同项目的列表,以最大化最终资本,并输出最终可获得的最多资本。

只考虑利润,那么这就是完美的贪心算法了。用小顶堆存资本,大顶堆存利润,循环K次,寻找满足资本的放入利润堆,然后从资本堆pop出去。

class Solution {
    
    
public:
    int findMaximizedCapital(int k, int W, vector<int>& Profits, vector<int>& Capital) {
    
    
        priority_queue<int> p;                                                    // 利润 大根堆
        priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> c;   // 资本 小根堆
        for (int i = 0; i < Capital.size(); i++) {
    
    
            c.emplace(make_pair(Capital[i], Profits[i]));
        }

        for (int i = 0; i < k; i++) {
    
    
            while (!c.empty() && c.top().first <= W) {
    
      // 资本小于等于W的项目,存入利润大根堆
                p.emplace(c.top().second);
                c.pop();
            }
            if(p.empty()) break;
            W += p.top();                         // 每次选利润最大的
            p.pop();
        }
        return W;
    }
};

  1. 下一个更大元素2
    给定一个循环数组(最后一个元素的下一个元素是数组的第一个元素),输出每个元素的下一个更大元素。数字 x 的下一个更大的元素是按数组遍历顺序,这个数字之后的第一个比它更大的数,这意味着你应该循环地搜索它的下一个更大的数。如果不存在,则输出 -1。

单调栈的典型应用,逆序比较方便

class Solution 
{
    
    
public:
    vector<int> nextGreaterElements(vector<int>& nums) 
    {
    
    
        int n = nums.size();
        vector<int> ret(n, -1);
        stack<int> m_stack;

        if (n == 0) return ret;

        for (int i = 2 * n - 1; i >= 0; i--)`在这里插入代码片`
        {
    
    
            while (m_stack.size() && m_stack.top() <= nums[i % n])
            {
    
    
                m_stack.pop();
            }

            if (m_stack.size())
            {
    
    
                ret[i % n] = m_stack.top();
            }

            m_stack.push(nums[i % n]);
        }

        return ret;
    }
};
  1. 七进制数
    给定一个整数,将其转化为7进制,并以字符串形式输出。

简单的进制运算

class Solution {
    
    
public:
    string convertToBase7(int num) 
    {
    
    
        bool low = false;
        string ret;
        if (num < 0) 
        {
    
    
            low = true;
            num = -num;           
        }

        while (num >= 7)
        {
    
    
            ret = (char)(num % 7 + '0') + ret;
            num = num / 7;
        }
        
        ret = (char)(num + '0') + ret;

        if (low) ret = '-' +ret;

        return ret;
    }
};
  1. 相对名次
    给出 N 名运动员的成绩,找出他们的相对名次并授予前三名对应的奖牌。前三名运动员将会被分别授予 “金牌”,“银牌” 和“ 铜牌”(“Gold Medal”, “Silver Medal”, “Bronze Medal”)。

用一个红黑树map保存,k为分数,v为索引,红黑树会自带排序,因此直接遍历即可输出名次

class Solution {
    
    
public:
    string tostr(int n){
    
    
        if(n==1) return "Gold Medal";
        if(n==2) return "Silver Medal";
        if(n==3) return "Bronze Medal";
        return to_string(n);
    }
    vector<string> findRelativeRanks(vector<int>& nums) {
    
    
        int n = nums.size();
        vector<string> result(n);
        map<int, int> m;
        for (int i=0; i<n; i++) m[nums[i]] = i;
        for (const auto &it:m) {
    
    
            result[it.second] = tostr(n--);
        }
        return result;
    }
};


  1. 完美数
    对于一个 正整数,如果它和除了它自身以外的所有 正因子 之和相等,我们称它为 「完美数」。给定一个 整数 n, 如果是完美数,返回 true,否则返回 false

只要找到平方根即可,然后将除数和余数都加起来

class Solution {
    
    
public:
    bool checkPerfectNumber(int num) 
    {
    
    
        if (num == 1) return false;
        int ret = 1;
        for (int i = 2; i <= num / i; i++)
        {
    
    
            if (num % i == 0)
            {
    
    
                ret += i;
                if (i * i != num)
                {
    
    
                    ret += num / i;
                }
            }    
        }
        return ret == num;
    }
};
  1. 出现次数最多的子树元素和
    给你一个二叉树的根结点,请你找出出现次数最多的子树元素和。一个结点的「子树元素和」定义为以该结点为根的二叉树上所有结点的元素之和(包括结点本身)。你需要返回出现次数最多的子树元素和。如果有多个元素出现的次数相同,返回所有出现次数最多的子树元素和(不限顺序)。

很简单的一道题:首先DFS获取每个字数元素和,然后遍历一遍取最大值即可

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
    
    
public:
    unordered_map<int,int> hash;
    int dfs(TreeNode* r){
    
    //返回以r为根的子树和
        if(!r) return 0;
        int ans =  r->val + dfs(r->left) + dfs(r->right);
        hash[ans]++;
        return ans;
    }
    vector<int> findFrequentTreeSum(TreeNode* root) {
    
    
        dfs(root);
        vector<int> ans;
        int maxx = 0;//出现次数的最大值
        for(auto [x, y] : hash){
    
    //寻找最大值
            if(y < maxx) continue;//小的直接忽略
            if(y > maxx) ans.clear(),maxx = y;//出现更大的 则清空 替换
            ans.push_back(x);
        }
        return ans; 
    }
};

猜你喜欢

转载自blog.csdn.net/u013354486/article/details/112641003