100264.最长的严格递增或递减子数组
给你一个整数数组 nums
。
返回数组 nums
中 严格递增 或 严格递减 的最长非空子数组的长度。
示例 1:
输入:nums = [1,4,3,3,2]
输出:2
解释:
nums
中严格递增的子数组有[1]
、[2]
、[3]
、[3]
、[4]
以及 [1,4]
。
nums
中严格递减的子数组有[1]
、[2]
、[3]
、[3]
、[4]
、[3,2]
以及 [4,3]
。
因此,返回 2
。
示例 2:
输入:nums = [3,3,3,3]
输出:1
解释:
nums
中严格递增的子数组有 [3]
、[3]
、[3]
以及 [3]
。
nums
中严格递减的子数组有 [3]
、[3]
、[3]
以及 [3]
。
因此,返回 1
。
示例 3:
输入:nums = [3,2,1]
输出:3
解释:
nums
中严格递增的子数组有 [3]
、[2]
以及 [1]
。
nums
中严格递减的子数组有 [3]
、[2]
、[1]
、[3,2]
、[2,1]
以及 [3,2,1]
。
因此,返回 3
。
提示:
1 <= nums.length <= 50
1 <= nums[i] <= 50
这个题目其实刚开始我是打算滑动窗口的,本地测试也是可以,但是提交力扣后就是显示不对,于是我又重新思考写了代码。
思路就是:
两个数组:
vector<int> inc(n, 1);
vector<int> dec(n, 1);
-
对于该数组,如果nums[i+1]>nums[i],那么记录递增数组的inc[i+1]=inc[i]+1;
#include<iostream>
#include<vector>
#include<algorithm>
#include<cstring>
using namespace std;
// int longestMonotonicSubarray(vector<int>& nums) {
// int n=nums.size();
// int ans=1; //最短肯定是1
// if (n <= 1) {
// return n; // 只有一个元素或者空数组的情况
// }
// //滑动窗口
// for(int i=0;i<n-1;i++){
// int cnt=1;
// int cnt1=1;
// int k=i,j=i;
// while(nums[k]<nums[k+1]&&k<n-1){
// cnt++;
// // cout<<nums[k]<<" "<<nums[k+1]<<"\n";
// if(k+1<n){
// k++;
// }
// }
// while(nums[j]>nums[j+1]&&j<n-1){
// cnt1++;
// if(j+1<n) j++;
// // cout<<nums[j]<<" "<<nums[j+1]<<"\n";
// }
// ans=max(ans,cnt);
// ans=max(ans,cnt1);
// }
// return ans;
// }
int longestMonotonicSubarray(vector<int>& nums) {
int n = nums.size();
if (n == 0) {
return 0;
}
vector<int> inc(n, 1);
vector<int> dec(n, 1);
for (int i = 1; i < n; i++) {
if (nums[i] > nums[i - 1]) {
inc[i] = inc[i - 1] + 1;
}
if (nums[i] < nums[i - 1]) {
dec[i] = dec[i - 1] + 1;
}
}
int maxLength = 0;
for (int i = 0; i < n; i++) {
maxLength = max(maxLength, max(inc[i], dec[i]));
}
return maxLength ;
}
int main(){
vector<int> nums;
nums={1,4,3,3,2};
cout<<longestMonotonicSubarray(nums);
return 0;
}
100242.满足距离约束且字典序最小的字符串
给你一个字符串 s
和一个整数 k
。
定义函数 distance(s1, s2)
,用于衡量两个长度为 n
的字符串 s1
和 s2
之间的距离,即:
- 字符
'a'
到'z'
按 循环 顺序排列,对于区间[0, n - 1]
中的i
,计算所有「s1[i]
和s2[i]
之间 最小距离」的 和 。
例如,distance("ab", "cd") == 4
,且 distance("a", "z") == 1
。
你可以对字符串 s
执行 任意次 操作。在每次操作中,可以将 s
中的一个字母 改变 为 任意 其他小写英文字母。
返回一个字符串,表示在执行一些操作后你可以得到的 字典序最小 的字符串 t
,且满足 distance(s, t) <= k
。
示例 1:
输入:s = "zbbz", k = 3 输出:"aaaz" 解释:在这个例子中,可以执行以下操作: 将 s[0] 改为 'a' ,s 变为 "abbz" 。 将 s[1] 改为 'a' ,s 变为 "aabz" 。 将 s[2] 改为 'a' ,s 变为 "aaaz" 。 "zbbz" 和 "aaaz" 之间的距离等于 k = 3 。 可以证明 "aaaz" 是在任意次操作后能够得到的字典序最小的字符串。 因此,答案是 "aaaz" 。
示例 2:
输入:s = "xaxcd", k = 4 输出:"aawcd" 解释:在这个例子中,可以执行以下操作: 将 s[0] 改为 'a' ,s 变为 "aaxcd" 。 将 s[2] 改为 'w' ,s 变为 "aawcd" 。 "xaxcd" 和 "aawcd" 之间的距离等于 k = 4 。 可以证明 "aawcd" 是在任意次操作后能够得到的字典序最小的字符串。 因此,答案是 "aawcd" 。
示例 3:
输入:s = "lol", k = 0 输出:"lol" 解释:在这个例子中,k = 0,更改任何字符都会使得距离大于 0 。 因此,答案是 "lol" 。
提示:
1 <= s.length <= 100
0 <= k <= 2000
s
只包含小写英文字母。
这个题还是比较简单的。就是遍历该字符串,s[0]这些越靠近'a'越好,最小就是'a',
特殊情况就是如果在字母表末端,且因为是循环,可以到'z',再到'a',这样字典序就一定会是小的
但是当这个字母到'a'和到'z'->'a'的距离一样时,肯定是直接到'a'而不是从'z'到'a',需要考虑这样的情况。
#include<iostream>
#include<vector>
#include<cstring>
using namespace std;
// string getSmallestString(string s, int k) {
// int n=s.length();
// if(k==0){
// return s;
// }
// //遍历s
// for(int i=0; i<n; i++){
// if(s[i]=='a'){
// //由于已经是最小的,不需要再改变
// k=k;
// }
// else if(s[i]=='z'){
// s[i]='a';
// k--;
// }
// else if('z'-s[i]+1<=k){
// s[i]='a';
// k=k-('z'-s[i])-1;
// }
// else{
// while(s[i]-'a'>=0&&k>=0){
// s[i]=s[i]-1;
// k--;
// if(s[i]=='a') break;
// }
// }
// if(k==0) return s;
// }
// return s;
// }
string getSmallestString(string s, int k){
int n=s.length();
if(k==0){
return s;
}
//遍历s
for(int i=0; i<n; i++){
if(s[i]=='a'){
//由于已经是最小的,不需要再改变
continue;
}else{
int a=s[i]-'a'; //到a的距离
int z='z'-s[i]+1; //该字母到z的距离+1 => 循环到a的距离
if(a<=k&&a<=z){ //如果该字母到a,z的距离一样,那么应该是直接考虑为a,而不是先到z再到a
s[i]='a';
k-=a;
}else if(z<=k){
s[i]='a';
k-=z;
}else{
s[i]-=k;
k=0;
}
}
if(k==0) return s;
}
return s;
}
int main(){
// :s = "zbbz", k = 3
string s="zzpwd";
int k=46;
cout<<getSmallestString(s,k)<<endl;
double ss=1995/2387;
cout<<ss;
return 0;
}
这些就是早上周赛时我写的题了,确实是平时练的太少了,写的太慢而且考虑边界情况也很少,幸好力扣是给看不通过的例子的,但是在我csp时就没有这样好的事情,导致很难查出自己代码哪里不对。。。
3107.使数组中位数等于K的最小操作数
给你一个整数数组 nums
和一个 非负 整数 k
。一次操作中,你可以选择任一元素 加 1
或者减 1
。
请你返回将 nums
中位数 变为 k
所需要的 最少 操作次数。
一个数组的中位数指的是数组按非递减顺序排序后最中间的元素。如果数组长度为偶数,我们选择中间两个数的较大值为中位数。
示例 1:
输入:nums = [2,5,6,8,5], k = 4
输出:2
解释:我们将 nums[1]
和 nums[4]
减 1
得到 [2, 4, 6, 8, 4]
。现在数组的中位数等于 k
。
示例 2:
输入:nums = [2,5,6,8,5], k = 7
输出:3
解释:我们将 nums[1]
增加 1 两次,并且将 nums[2]
增加 1 一次,得到 [2, 7, 7, 8, 5]
。
示例 3:
输入:nums = [1,2,3,4,5,6], k = 4
输出:0
解释:数组中位数已经等于 k
了。
提示:
1 <= nums.length <= 2 * 105
1 <= nums[i] <= 109
1 <= k <= 109
没啥好说的,挺简单的感觉,就是写的太慢了
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
long long minOperationsToMakeMedianK(vector<int>& nums, int k) {
sort(nums.begin(), nums.end());
// 255681 7
int n=nums.size();
int mid=0,m=0;
long long ans=0;
if(n%2!=0) {
mid=nums[(n-1)/2];
m=(n-1)/2;
}
else{
//已经排序了,所以一定是nums[n/2]
// if(nums[n/2]==nums[n/2-1]){
// if(nums[n/2]>k){
// mid=nums[n/2];
// m=n/2;
// }
// else{
// mid=nums[n/2];
// m=n/2;
// }
// }
mid=nums[n/2];
m=n/2;
}
if(mid==k){
return 0;
}
else if(mid<k){
for(int i=m;i<n;i++){
if(nums[i]<k){
ans+=k-nums[i];
}
else{
break;
}
}
}
else{
//mid>k
for(int i=m;i>=0;i--){
if(nums[i]>k){
ans+=nums[i]-k;
// cout<<" "<<nums[i]<<endl;
}
else{
break;
}
}
}
return ans;
}
int main(){
vector<int> nums={1,2,3,4,5,6};
//1 2 3 4 5 6
//
int k=4;
cout<<minOperationsToMakeMedianK(nums,k)<<endl;
return 0;
}