Leetcode 第275场周赛题解

本文介绍了LeetCode第275场周赛的四道题目,包括重排字符形成目标字符串、价格减免、使数组按非递减顺序排列和到达角落需要移除障碍物的最小数目。分别使用了枚举、模拟、构造单调栈和0-1 BFS等算法,详细解析了思路和代码实现。
摘要由CSDN通过智能技术生成

Leetcode 第275场周赛题解

2287. 重排字符形成目标字符串

原题链接

思路

记 s 里字母 c 出现的次数是 cnt1[c],target 里字母 c 出现的次数是 cnt2[c]。枚举所有在 target 里出现的字母 c,那么 s 里的 c 最多只能凑出 floor(cnt1[c] / cnt2[c]) 个 target。答案就是 floor(cnt1[c] / cnt2[c]) 的最小值。

算法标签 枚举

代码

class Solution {
public:
    int rearrangeCharacters(string s, string target) {
        vector<int> c(26, 0);
        for(auto x : s){
            c[x-'a']++;
        }
        vector<int> y(26, 0);
        for(auto x : target){
            y[x-'a']++;
        }
        int ret = 0x3f3f3f3f;
        for(int i=0; i<26; ++i){
            if(y[i]){
                ret = min(ret, c[i] / y[i]);
            }
        }
        return ret;
    }
};

2288. 价格减免

原题链接

算法标签 模拟

WA代码

WAn发, 呜呜呜, 如果有大佬希望指导一下哈
在这里插入图片描述

class Solution {    
public:
    string discountPrices(string sentence, int discount) {
        string ss="", sss="";
        //存储原单词
	    vector<string> str;
	    //存储处理后单词
        vector<string> str1;
        int temp=-1;
      	// 单词划分 
	    for(int i=0;i<sentence.size();++i){
		    if(sentence[i]==' '){
			    for(int j=temp+1;j<i;++j){
				    ss+=sentence[j];
			    }
			    str.push_back(ss);
			    ss="";
			    temp=i;
		    }
	    }
	    // 尾部单词
	    for(int j=temp+1;j<sentence.size();++j){
		    ss+=sentence[j];	
	    }
	    str.push_back(ss);
        for(auto s:str){
            bool flag=false;
            // 判断是否为价格
            for(int i=0;i<s.size();++i){
                if(!i&&s[i]=='$'&&i+1<s.size()||i&&(s[i]-'0')>=0&&(s[i]-'0')<=9||i&&s[i]=='.'){
                    continue;
                }
                else{
                    flag=true;
                }
            }
            if(flag){
                str1.push_back(s);
            }
            else{
            	//整数部分位数
                int a=to_string((stoll(s.substr(1))*(100-discount)*1/100)).size();
                //整数部分位数+保留位数
                str1.push_back("$"+(to_string((stoll(s.substr(1))*(100.0-discount*1.0)*1.0/100.0))).substr(0, a+3));
            }
        }
        // 以字符形式输出
        for(int i=0;i<str1.size();++i){
            if(i==str1.size()-1)sss+=str1[i];
            else{
                sss+=(str1[i]+" ");
            }
        }
        return sss;
    }
};

2289. 使数组按非递减顺序排列

原题链接

思路

① 若当前元素需要被删除, 则位于其左边且小于该元素的要全被删除, 故当前元素删除时间为位于其左边且小于该元素的要全被删除时间加一
②若序列为单调递减增序列,则该序列一定是被依次删除, 即该序列尾部元素(最大值)覆盖前面较小值的状态
因此,我们可以用一个单调递减栈存储元素及其被删除的时刻,当遇到一个不小于栈顶的元素 x 时,就不断弹出栈顶元素,并取弹出元素被删除时刻的最大值,
这样就得到了所需要计算的时刻的最大值
然后将 x 及 maxT+1入栈。注意如果此时栈为空,说明前面没有比 x 大的元素,x 无法被删除,即 maxT=0,这种情况需要将 x 及 0 入栈。

算法标签 构造 单调栈

代码

class Solution {
public:
    int totalSteps(vector<int> &nums) {
        int ans = 0;
        stack<pair<int, int>> st;
        for (int num : nums) {
            int maxT = 0;
            while (!st.empty() && st.top().first <= num) {
                maxT = max(maxT, st.top().second);
                st.pop();
            }
            maxT = st.empty() ? 0 : maxT + 1;
            ans = max(ans, maxT);
            st.emplace(num, maxT);
        }
        return ans;
    }
};

2290. 到达角落需要移除障碍物的最小数目

原题链接

思路

① 把障碍物当作可以经过的单元格,经过它的代价为 1,空单元格经过的代价为 0
② 问题转化成从起点到终点的最短路。
可以用 0-1 BFS 来将时间复杂度优化至 O(mn)

算法标签 图论 BFS

代码

class Solution {
    static constexpr int dirs[4][2] = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}};

public:
    int minimumObstacles(vector<vector<int>> &grid) {
        int m = grid.size(), n = grid[0].size();
        int dis[m][n];
        memset(dis, 0x3f, sizeof(dis));
        dis[0][0] = 0;
        deque<pair<int, int>> q;
        q.emplace_front(0, 0);
        while (!q.empty()) {
            auto [x, y] = q.front();
            q.pop_front();
            for (auto &[dx, dy] : dirs) {
                int nx = x + dx, ny = y + dy;
                if (0 <= nx && nx < m && 0 <= ny && ny < n) {
                    int g = grid[nx][ny];
                    if (dis[x][y] + g < dis[nx][ny]) {
                        dis[nx][ny] = dis[x][y] + g;
                        // 遇到 0 就该点放入队头,优先走短路,利用双端队列的性质极大地优化了时间复杂度
                        g == 0 ? q.emplace_front(nx, ny) : q.emplace_back(nx, ny);
                    }
                }
            }
        }
        return dis[m - 1][n - 1];
    }
};

3, 4题解主要参考灵神
原创不易
转载请标明出处
如果对你有所帮助 别忘啦点赞支持哈
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

飞滕人生TYF

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值