LeetCode第359场周赛
判别首字母缩略词 简单
给你一个字符串数组 words
和一个字符串 s
,请你判断 s
是不是 words
的 首字母缩略词 。
如果可以按顺序串联 words
中每个字符串的第一个字符形成字符串 s
,则认为 s
是 words
的首字母缩略词。例如,"ab"
可以由 ["apple", "banana"]
形成,但是无法从 ["bear", "aardvark"]
形成。
如果 s
是 words
的首字母缩略词,返回 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 数组的最小总和 中等
给你两个整数 n
和 k
。
对于一个由 不同 正整数组成的数组,如果其中不存在任何求和等于 k
的不同元素对,则称其为 k-avoiding
数组。
返回长度为 n
的 k-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
表示数轴上的房屋数量,编号从 0
到 n - 1
。
另给你一个二维整数数组 offers
,其中 offers[i] = [starti, endi, goldi]
表示第i
个买家想要以 goldi
枚金币的价格购买从 starti
到 endi
的所有房屋。
作为一名销售,你需要有策略地选择并销售房屋使自己的收入最大化。
返回你可以赚取的金币的最大数目。
注意 同一所房屋不能卖给不同的买家,并且允许保留一些房屋不进行出售。
示例 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[i−1],dp[starti−1]+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,不能表示。