【LeetCode周赛】第 359 场周赛

判别首字母缩略词 简单

给你一个字符串数组 words 和一个字符串 s ,请你判断 s 是不是 words 的 首字母缩略词 。

如果可以按顺序串联 words 中每个字符串的第一个字符形成字符串 s ,则认为 swords 的首字母缩略词。例如,"ab" 可以由 ["apple", "banana"] 形成,但是无法从 ["bear", "aardvark"] 形成。

如果 swords 的首字母缩略词,返回 true ;否则,返回 false

示例 1

输入:words = [“alice”,“bob”,“charlie”], s = “abc”
输出:true
解释:words 中 “alice”、“bob” 和 “charlie” 的第一个字符分别是 ‘a’、‘b’ 和 ‘c’。因此,s = “abc” 是首字母缩略词。

示例 2:

输入:words = [“an”,“apple”], s = “a”
输出:false
解释:words 中 “an” 和 “apple” 的第一个字符分别是 ‘a’ 和 ‘a’。
串联这些字符形成的首字母缩略词是 “aa” 。
因此,s = “a” 不是首字母缩略词。

示例 3:

输入:words = [“never”,“gonna”,“give”,“up”,“on”,“you”], s = “ngguoy”
输出:true
解释:串联数组 words 中每个字符串的第一个字符,得到字符串 “ngguoy” 。
因此,s = “ngguoy” 是首字母缩略词。

提示:

  • 1 <= words.length <= 100
  • 1 <= words[i].length <= 10
  • 1 <= s.length <= 100
  • words[i]s 由小写英文字母组成

分析: 遍历比较一下就好了。

代码:

class Solution {
public:
    bool isAcronym(vector<string>& words, string s) {
        if(words.size() != s.length()) return false;
        for(int i=0;i<words.size();i++){
            if(words[i][0]!=s[i])return false;
        }
        return true;
    }
};


k-avoiding 数组的最小总和 中等

给你两个整数 nk

对于一个由 不同 正整数组成的数组,如果其中不存在任何求和等于 k 的不同元素对,则称其为 k-avoiding 数组。

返回长度为 nk-avoiding 数组的可能的最小总和。

示例 1

输入:n = 5, k = 4
输出:18
解释:设若 k-avoiding 数组为 [1,2,4,5,6] ,其元素总和为 18 。
可以证明不存在总和小于 18 的 k-avoiding 数组。

示例 2

输入:n = 2, k = 6
输出:3
解释:可以构造数组 [1,2] ,其元素总和为 3 。
可以证明不存在总和小于 3 的 k-avoiding 数组。

提示:

  • 1 <= n, k <= 50

分析: 构成的数组中,任意两个数的和不能与k相等。对于数分两种情况:
1、number < k : 存在 number_1 + number_2 = k, 此时选择更小的那个数
2、number >= k:此时不存在任意两数和等于k,因此可以直接选择。
先从1开始遍历,直至数组长度与n相等。
代码:

class Solution {
public:
    int minimumSum(int n, int k) {
        int ans =0;
        for(int i=1;n>0;n--,i++){
            if(k<=i) ans+=i;
            else{
                int tmp=k-i;
                if(tmp<i) n++;
                else{ans+=i;}
            }
        }
        return ans;
    }
};


销售利润最大化 中等

给你一个整数 n 表示数轴上的房屋数量,编号从 0n - 1

另给你一个二维整数数组 offers ,其中 offers[i] = [starti, endi, goldi] 表示第i 个买家想要以 goldi 枚金币的价格购买从 startiendi 的所有房屋。

作为一名销售,你需要有策略地选择并销售房屋使自己的收入最大化。

返回你可以赚取的金币的最大数目。

注意 同一所房屋不能卖给不同的买家,并且允许保留一些房屋不进行出售。

示例 1

输入:n = 5, offers = [[0,0,1],[0,2,2],[1,3,2]]
输出:3
解释: 有 5 所房屋,编号从 0 到 4 ,共有 3 个购买要约。 将位于 [0,0] 范围内的房屋以 1 金币的价格出售给第 1 位买家,并将位于 [1,3] 范围内的房屋以 2 金币的价格出售给第 3 位买家。
可以证明我们最多只能获得 3 枚金币。

示例 2

输入:n = 5, offers = [[0,0,1],[0,2,10],[1,3,2]]
输出:10
解释:有 5 所房屋,编号从 0 到 4 ,共有 3 个购买要约。 将位于 [0,2] 范围内的房屋以 10 金币的价格出售给第 2 位买家。
可以证明我们最多只能获得 10 枚金币。

提示:

  • 1 <= n <= 10^5
  • 1 <= offers.length <= 10^5
  • offers[i].length == 3
  • 0 <= starti <= endi <= n - 1
  • 1 <= goldi <= 10^3

赛后补题学习

分析: 因为offers.length可能会比较大,直接进行暴力比较肯定会超时。
这里使用DP减少重复计算子问题,节省时间。
构建数组dp[n]dp[i]保存的值是前i座房子的最大销售额:
d p [ i ] = m a x ( d p [ i − 1 ] , d p [ s t a r t i − 1 ] + c i ) dp[i]=max(dp[i-1], dp[start_i - 1] + c_i) dp[i]=max(dp[i1],dp[starti1]+ci)
最终dp[n]即存储了所有的房子的最大销售额。

代码:

class Solution {
public:
    int maximizeTheProfit(int n, vector<vector<int>>& offers) {
        vector<vector<pair<int, int>>> v(n);
        for(auto offer : offers){
            v[offer[1]].emplace_back(offer[0], offer[2]);
        } 
        int dp[n+1];
        memset(dp,0,sizeof(dp));
        for(int end=0;end<n;end++){
            dp[end+1]=dp[end];
            for(auto &offer : v[end]){
                dp[end+1]=max(dp[end+1], dp[offer.first]+offer.second);
            }
        }
        return dp[n];
    }
};

代码中dp[0]默认为0,房子的编号为1~n,因为0前面是-1,不能表示。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值