第301场周赛补题

T1:装满杯子需要的最短总时长
现有一台饮水机,可以制备冷水、温水和热水。每秒钟,可以装满 2 杯 不同 类型的水或者 1 杯任意类型的水。

给你一个下标从 0 开始、长度为 3 的整数数组 amount ,其中 amount[0]、amount[1] 和 amount[2] 分别表示需要装满冷水、温水和热水的杯子数量。返回装满所有杯子所需的 最少 秒数。

这个题目一开始我的想法是先将amount排序,然后分l两种情况:
1、amount[0]+amount[1]<=amount[2];则直接返回amount[2]
2、amount[0]+amount[1]>amount[2]。这种情况需要考虑到使用次数最少,则要将三种热水进行完美的组合。这里的想法是一直将数量最高的和数量最低的组合操作。(操作过程中注意不断比较)。

class Solution {
public:
    int fillCups(vector<int>& amount) {
        
        
        int s = 0;
        for(auto x : amount){
            if(x == 0)s ++;
        }
        
        
        int n = 0;
        sort(amount.begin(),amount.end());
        if(amount[0]+amount[1] <= amount[2]) return amount[2];
        
        while((amount[0] + amount[1] + amount[2]) && amount[1] != 0 )
        {
            n ++;
            amount[s] --;
            amount[2] --;
            if(amount[s] == 0)s ++;
            if(amount[1] > amount[2]){
                int p = amount[1];
                amount[1] = amount[2];
                amount[2] = p;
            }
            
            
            
        }
        if(amount[2] == 0)return n;
        else return n + amount[2];

    }
};

T2:无限集中最小数字
现有一个包含所有正整数的集合 [1, 2, 3, 4, 5, …] 。

实现 SmallestInfiniteSet 类:

SmallestInfiniteSet() 初始化 SmallestInfiniteSet 对象以包含 所有 正整数。
int popSmallest() 移除 并返回该无限集中的最小整数。
void addBack(int num) 如果正整数 num 不 存在于无限集中,则将一个 num 添加 到该无限集中。

这个题目看完题解觉得蛮简单,但是自己写的时候也是没有想到。set会对数字进行自动排序,所以在移除最小正整数时只需要移除最开始的一个就好了。

class SmallestInfiniteSet {
    int x;
    set<int>nums;
public:
    SmallestInfiniteSet() {
        x=1;
        nums.clear();
    }
    
    int popSmallest() {
        if(nums.empty()){
            int y = x ;
            x ++ ;
            return y;
        }
        else{
            auto n = nums.begin();
            int y = *n ;
            nums.erase(y);
            return y;
        }
    }
    
    void addBack(int num) {
        if(num<x){
            nums.insert(num);
        }
    }
};

T3:移动片段得到字符串
给你两个字符串 start 和 target ,长度均为 n 。每个字符串 仅 由字符 ‘L’、‘R’ 和 ‘_’ 组成,其中:

字符 ‘L’ 和 ‘R’ 表示片段,其中片段 ‘L’ 只有在其左侧直接存在一个 空位 时才能向 左 移动,而片段 ‘R’ 只有在其右侧直接存在一个 空位 时才能向 右 移动。
字符 ‘_’ 表示可以被 任意 ‘L’ 或 ‘R’ 片段占据的空位。
如果在移动字符串 start 中的片段任意次之后可以得到字符串 target ,返回 true ;否则,返回 false 。

这个题目的终极奥义在start和target中R和L的顺序不能变。所以我们可以用类似直接遍历,一个一个比较,如果遇到不为"_"和相同的就直接退出,说明不能得到目标值,若最后可以遍历到字符串终点,则说明可以。

class Solution {
public:
    bool canChange(string start, string target) {
        int n = start.size();
        int i = 0 , j = 0 ;
        while(i < n && j < n ){
             while(i < n && start[i] == '_') ++i;
             while(j < n && target[j] == '_') ++j;
             if(i < n || j < n){
                 if(i >= n && j >= n) return false;
                 if(start[i] != target[j]) return false;
                 if(start[i] == 'L' && i < j) return false;
                 if(start[i] == 'R' && i > j) return false;
                ++i;
                ++j;
             }
        }
        return true ;
    } 
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值