1984.学生分数的最小差值
给你一个 下标从 0 开始 的整数数组 nums
,其中 nums[i]
表示第 i
名学生的分数。另给你一个整数 k
。
从数组中选出任意 k
名学生的分数,使这 k
个分数间 最高分 和 最低分 的 差值 达到 最小化 。
返回可能的 最小差值 。
示例 1:
输入:nums = [90], k = 1 输出:0 解释:选出 1 名学生的分数,仅有 1 种方法: - [90] 最高分和最低分之间的差值是 90 - 90 = 0 可能的最小差值是 0
示例 2:
输入:nums = [9,4,1,7], k = 2 输出:2 解释:选出 2 名学生的分数,有 6 种方法: - [9,4,1,7] 最高分和最低分之间的差值是 9 - 4 = 5 - [9,4,1,7] 最高分和最低分之间的差值是 9 - 1 = 8 - [9,4,1,7] 最高分和最低分之间的差值是 9 - 7 = 2 - [9,4,1,7] 最高分和最低分之间的差值是 4 - 1 = 3 - [9,4,1,7] 最高分和最低分之间的差值是 7 - 4 = 3 - [9,4,1,7] 最高分和最低分之间的差值是 7 - 1 = 6 可能的最小差值是 2
提示:
1 <= k <= nums.length <= 1000
0 <= nums[i] <= 105
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
int minimumDifference(vector<int>& nums, int k) {
sort(nums.begin(), nums.end());
int ans=100000;
for(int i = 0; i+k-1 < nums.size();i++){
ans=min(ans,nums[i+k-1]-nums[i]);
}
return ans;
}
int main(){
vector<int>nums={9,4,1,7};
int k=2;
int target=minimumDifference(nums,k);
cout<<target;
return 0;
}
2653.滑动子数组的美丽值
给你一个长度为 n
的整数数组 nums
,请你求出每个长度为 k
的子数组的 美丽值 。
一个子数组的 美丽值 定义为:如果子数组中第 x
小整数 是 负数 ,那么美丽值为第 x
小的数,否则美丽值为 0
。
请你返回一个包含 n - k + 1
个整数的数组,依次 表示数组中从第一个下标开始,每个长度为 k
的子数组的 美丽值 。
-
子数组指的是数组中一段连续 非空 的元素序列。
示例 1:
输入:nums = [1,-1,-3,-2,3], k = 3, x = 2 输出:[-1,-2,-2] 解释:总共有 3 个 k = 3 的子数组。 第一个子数组是[1, -1, -3]
,第二小的数是负数 -1 。 第二个子数组是[-1, -3, -2]
,第二小的数是负数 -2 。 第三个子数组是[-3, -2, 3] ,第二小的数是负数 -2 。
示例 2:
输入:nums = [-1,-2,-3,-4,-5], k = 2, x = 2 输出:[-1,-2,-3,-4] 解释:总共有 4 个 k = 2 的子数组。[-1, -2] 中第二小的数是负数 -1 。
[-2, -3] 中第二小的数是负数 -2 。
[-3, -4] 中第二小的数是负数 -3 。
[-4, -5] 中第二小的数是负数 -4 。
示例 3:
输入:nums = [-3,1,2,-3,0,-3], k = 2, x = 1 输出:[-3,0,-3,-3,-3] 解释:总共有 5 个 k = 2 的子数组。[-3, 1] 中最小的数是负数 -3 。
[1, 2] 中最小的数不是负数,所以美丽值为 0 。
[2, -3] 中最小的数是负数 -3 。
[-3, 0] 中最小的数是负数 -3 。
[0, -3] 中最小的数是负数 -3 。
提示:
n == nums.length
1 <= n <= 105
1 <= k <= n
1 <= x <= k
-50 <= nums[i] <= 50
最初的代码是这样的:
#include <iostream>
#include<vector>
#include<cstring>
#include<algorithm>
using namespace std;
vector<int> getSubarrayBeauty(vector<int>& nums, int k, int x) {
vector<int>ans;
for(int i = 0; i+k-1 < nums.size();i++){
//对于窗口[i,k+i-1]排序
vector<int>target(nums.begin() + i, nums.begin() + i + k);
sort(target.begin(), target.end());
if(target[x-1]<0){
ans.push_back(target[x-1]);
}
else{
ans.push_back(0);
}
}
return ans;
}
int main(){
vector<int>nums={-3,1,2,-3,0,-3};
int k=2;
int x=1;
vector<int>target=getSubarrayBeauty(nums,k,x);
for(int i=0;i<5;i++){
cout<<target[i]<<endl;
}
return 0;
}
然而超时了。。。。
#include <iostream>
#include<vector>
#include<cstring>
#include<algorithm>
using namespace std;
vector<int> getSubarrayBeauty(vector<int>& nums, int k, int x) {
const int BIAS=50;
int cnt[BIAS*2+1]{},n=nums.size();
//先往窗口添加k-1个数
for(int i=0;i<k-1;i++){
cnt[nums[i]+BIAS]++;
}
vector<int>ans(n-k+1);
for(int i=k-1;i<n;i++){
cnt[nums[i]+BIAS]++; //进入窗口
int left=x;
for(int j=0;j<BIAS;j++){ //暴力枚举负数范围[-50,-1] 如果是>=0的数字,它就不会出现在这里了
left=left-cnt[j];
if(left<=0){ //找到美丽值
ans[i-k+1]=j-BIAS;
break;
}
}
cnt[nums[i-k+1]+BIAS]--; //离开窗口
}
return ans;
}
int main(){
vector<int>nums={-3,1,2,-3,0,-3};
int k=2;
int x=1;
vector<int>target=getSubarrayBeauty(nums,k,x);
for(int i=0;i<5;i++){
cout<<target[i]<<endl;
}
return 0;
}
这是我看灵茶的思路写的,就是基于k-1个窗口,对各数字进行计数排序,然后每次向前滑动一个窗口,则
cnt[nums[i]+BIAS]++;//进入
{。。。}
cnt[nums[i-k+1]+BIAS]--; //离开窗口
那么对于求第x小的数,则暴力枚举【-50,-1】的数字的个数,当x减去这么多数字的频率之后,此时的数字则为所求结果,但是如果该x小的数不在这个范围内,则为0即可。
1493.删掉一个元素以后全为1的最长数组
给你一个二进制数组 nums
,你需要从中删掉一个元素。
请你在删掉元素的结果数组中,返回最长的且只包含 1 的非空子数组的长度。
如果不存在这样的子数组,请返回 0 。
提示 1:
输入:nums = [1,1,0,1] 输出:3 解释:删掉位置 2 的数后,[1,1,1] 包含 3 个 1 。
示例 2:
输入:nums = [0,1,1,1,0,1,1,0,1] 输出:5 解释:删掉位置 4 的数字后,[0,1,1,1,1,1,0,1] 的最长全 1 子数组为 [1,1,1,1,1] 。
示例 3:
输入:nums = [1,1,1] 输出:2 解释:你必须要删除一个元素。
提示:
1 <= nums.length <= 105
nums[i]
要么是0
要么是1
。
#include<iostream>
#include<vector>
using namespace std;
int longestSubarray(vector<int>& nums) {
int n=nums.size();
vector<int>pre(n),suf(n);
pre[0]=nums[0];
for(int i=1;i<n;i++){
pre[i]=nums[i]?pre[i-1]+1:0;
}
suf[n-1]=nums[n-1];
for(int i=n-2;i>=0;i--){
suf[i]=nums[i]?suf[i+1]+1:0;
}
int ans=0;
for(int i=0;i<n;i++){
int preSum= i==0?0:pre[i-1];
int sufSum= i==n-1?0:suf[i+1];
ans=max(ans,sufSum+preSum);
}
return ans;
}
int main(){
vector<int>nums={1,1,0,1};
int tar=longestSubarray(nums);
cout<<tar;
return 0;
}