LeetCode第288场周赛前3题题解(堆的使用)

- 本人的LeetCode账号:魔术师的徒弟,欢迎关注获取每日一题题解,快来一起刷题呀~

一、按奇偶性交换后的最大数字

6037. 按奇偶性交换后的最大数字

  本题的思路比较直接,我们先把数组转成字符串s,然后把它的奇数项和偶数项分别放到不同的数组中,然后排序,然后遍历一遍s,如果遇到奇数,就把排好序的奇数数组的最后一位加上,然后奇数数组指针移动一下,如果遇到偶数,就把排好序的欧数数组的指针指向的那一位加上,然后移动一下偶数数组指针,最后把答案的字符串转换回数字即可。

class Solution {
public:
    int largestInteger(int num) 
    {
        vector<char> even;// 偶数
        vector<char> odd;// 奇数
        string s = to_string(num);
        for (char ch : s)
        {
            int number = ch - '0';
            if (number % 2) odd.push_back(ch);
            else even.push_back(ch);
        }
        sort(odd.begin(), odd.end());
        sort(even.begin(), even.end());
        string res;
        int i = even.size() - 1;
        int j = odd.size() - 1;
        for (char ch : s)
        {
            int number = ch - '0';
            if (number % 2) res += odd[j--];
            else res += even[i--];
        }    
        return stoi(res);
    }
};

二、向表达式添加括号后的最小结果

6038. 向表达式添加括号后的最小结果

  本题的破局点在于看到表达式的长度仅仅是3~10,所以可以穷举所有插入括号的位置,但是穷举有非常多的细节的地方,当时画图加肉眼debug花了我好长的时间,这题还是挺烦人的。

class Solution {
public:
    string minimizeResult(string expression)
	{
    	int addpos = expression.find('+', 0);
    	int n = expression.size();
    	string res;
    	int minnum = 0x3f3f3f3f;
    	for (int i = 0; i < addpos; ++i)
    	{
        	for (int j = addpos + 1; j < n; ++j)
        	{
            	// (插入在i位置前面 )插入在j位置后面
            	if (i == 0 && j == n - 1)
            	{
                	int num1 = stoi(expression.substr(0, addpos));
                	int num2 = stoi(expression.substr(addpos + 1));
                	int sum = num1 + num2;
                	if (sum < minnum)
                	{
                    	minnum = sum;
                    	res = "(" + expression + ")";
                	}
            	}
            	else
            	{
                	if (i == 0)
                	{
                    	int num1 = stoi(expression.substr(0, addpos));
                    	int num2 = stoi(expression.substr(addpos + 1, j - addpos));
                    	int num3 = stoi(expression.substr(j + 1));
                    	int val = (num1 + num2) * num3;
                    	if (val < minnum)
                    	{
                        	minnum = val;
                        	res = expression;
                        	res.insert(0, "(");
                        	res.insert(j + 2, ")");
                    	}
                	}
                	else if (j == n - 1)
                	{
                   		int num3 = stoi(expression.substr(addpos + 1));
                    	int num1 = stoi(expression.substr(0, i));
                    	int num2 = stoi(expression.substr(i, addpos - i));
                    	int val = num1 * (num2 + num3);
                    	if (val < minnum)
                    	{
                        	minnum = val;
                        	res = expression;
                        	res.push_back(')');
                        	res.insert(i, "(");
                    	}
                	}
                	else
                	{
                    	int num1 = stoi(expression.substr(0, i));
                    	int num2 = stoi(expression.substr(i, addpos - i));
                    	int num3 = stoi(expression.substr(addpos + 1, j - addpos));
                    	int num4 = stoi(expression.substr(j + 1));
                    	int val = num1 * (num2 + num3) * num4;
                    	if (val < minnum)
                    	{
                        	minnum = val;
                        	res = expression;
                        	res.insert(i, "(");
                        	res.insert(j + 2, ")");
                    	}
                	}
            	}
        	}
    	}
    	return res;
	}
};

三、K 次增加后的最大乘积

6039. K 次增加后的最大乘积

  本题可以这样考虑:因为我们只能不断的给一个数增加1,不能给数变小,所以对n个数的乘积,每次增加1贡献最大的值一定是它最小的数(这点可以通过偏导数验证),所以我们可以维护一个小根堆,每次都把数组中最小的元素(也就是堆顶)取出,加1然后扔回堆里,做k次操作后,得到的值就是最大的。

  对于本题的数值范围,我们知道两个1e9数量级的数相乘是会爆int的,但是不会爆long long,所以乘积时可以强转一下然后取模。

class Solution {
public:
    typedef long long LL;
    const int mod = 1e9 + 7;
    int maximumProduct(vector<int>& nums, int k) 
    {
        priority_queue<int, vector<int>, greater<int>> pq(nums.begin(), nums.end());
        while (k--)
        {
            int num = pq.top();
            pq.pop();
            pq.push(++num);
        }
        int res = 1;
        while (!pq.empty())
        {
            int num = pq.top();
            pq.pop();
            res = (LL)res * num % mod;
        }
        return res;
    }
};

四、扯淡

  第四题题解看了好久还是不会= =,还是太菜了。

评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值