LeetCode第272场周赛
T1 5956. 找出数组中的第一个回文字符串
题目描述:给你一个字符串数组,找出第一个是回文的字符串。
思路:遍历即可
时间复杂度:\(O(\sum|s|)\)
参考代码:
class Solution {
public:
string firstPalindrome(vector<string>& words) {
string res;
for(auto s : words){
string t = s;
reverse(t.begin() , t.end());
if(s == t){res = s; break;}
}
return res;
}
};
T2 5957. 向字符串添加空格
题目描述:给你一个字符串,再给你一个数组spaces,spaces[i]表示在字符串的第\(i\)个位置的前面添加一个空格。
思路:根据题目描述直接模拟即可
时间复杂度:\(O(n)\)
参考代码:
class Solution {
public:
string addSpaces(string s, vector<int>& spaces) {
string res;
int idx = 0, n = spaces.size();
for(int i = 0 ; i < s.size() ; ++i){
if(idx < n && i == spaces[idx]) res += ' ', ++idx;
res += s[i];
}
return res;
}
};
T3 5958. 股票平滑下跌阶段的数目
题目描述:给你一个整数数组 prices
,表示一支股票的历史每日股价,其中 prices[i]
是这支股票第 i
天的价格。
一个 平滑下降的阶段 定义为:对于 连续一天或者多天 ,每日股价都比 前一日股价恰好少 1
,这个阶段第一天的股价没有限制。
请你返回 平滑下降阶段 的数目。
思路:比较明显的\(dp\),定义状态\(f_i\)表示以第\(i\)个数结尾的平滑下降阶段的数目,显然有转移方程:
最终答案为:\(\sum_{i = 1}^n f_i\) 。注意开long long
时间复杂度:\(O(n)\)
参考代码:
class Solution {
public:
long long getDescentPeriods(vector<int>& prices) {
int n = prices.size();
vector<int> f(n + 1 , 0);
f[1] = 1;
for(int i = 2 ; i <= n ; ++i){
f[i] = 1;
if(prices[i - 1] + 1 == prices[i - 2]) f[i] += f[i - 1];
}
long long res = 0;
for(auto num : f) res += num;
return res;
}
};
T4 5959. 使数组 K 递增的最少操作次数
题目描述:给你一个下标从 0 开始包含 n
个正整数的数组 arr
,和一个正整数 k
。
如果对于每个满足 \(k \leq i \leq n-1\) 的下标 \(i\) ,都有 \(arr[i-k] \leq arr[i]\) ,那么我们称 \(arr\)是 \(K\)递增的。
-
比方说,
arr = [4, 1, 5, 2, 6, 2]
对于
k = 2
是 K 递增的,因为:
- \(arr[0] <= arr[2] (4 <= 5)\)
- \(arr[1] <= arr[3] (1 <= 2)\)
- \(arr[2] <= arr[4] (5 <= 6)\)
- \(arr[3] <= arr[5] (2 <= 2)\)
-
但是,相同的数组
arr
对于k = 1
不是 K 递增的(因为 \(arr[0] > arr[1]\)),对于 \(k = 3\) 也不是 \(K\) 递增的(因为 \(arr[0] > arr[3]\) )。
每一次 操作 中,你可以选择一个下标 i
并将 arr[i]
改成任意 正整数。
请你返回对于给定的 k
,使数组变成 \(K\) 递增的 最少操作次数 。
思路:显然可以把原数组分为\(k\)组,对于每一组而言,问题转化成改变最少的数字使得数组非严格单调递增,比较经典的题目,考虑求出该数组的最长非严格单调递增子序列的长度,设为\(len\),则需要修改的就是\(n - len\),做\(k\)组即可。
时间复杂度:\(O(nlogn)\)
参考代码:
class Solution {
private:
int LIS(vector<int>& arr){
int len = 1;
int n = arr.size();
vector<int> d(n + 2 , 0);
d[len] = arr[0];
for(int i = 1 ; i < arr.size() ; ++i){
if(arr[i] >= d[len]) d[++len] = arr[i];
else{
int lr = 1 , rs = len , pos = -1;
while(lr <= rs){
int mid = lr + rs >> 1;
if(d[mid] <= arr[i]) lr = mid + 1;
else rs = mid - 1, pos = mid;
}
d[pos] = arr[i];
}
}
return n - len;
}
public:
int kIncreasing(vector<int>& arr, int k) {
int res = 0;
vector<int>f;
int n = arr.size();
for(int i = 0 ; i < k ; ++i){
for(int j = i ; j < n ; j += k) f.push_back(arr[j]);
res += LIS(f);
f.clear();
}
return res;
}
};
推荐题目:
300. 最长递增子序列
P3902 递增
P1020 [NOIP1999 普及组] 导弹拦截
P1439 【模板】最长公共子序列
作者:cherish.
出处:https://home.cnblogs.com/u/cherish-/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。