力扣2653. 滑动子数组的美丽值
这一题的大意是指给出一个长度为n的数组,然后让我们找到每一个长度为k的子数组的美丽值,所谓美丽值就是如果子数组中第x个数是负数,那么美丽值就是这个数,否则就是0.
现在让我们找所有长度为k的子数组的美丽值。
看到子数组长度为k,很明显建立滑动窗口,**重点就在于如何快速的找到滑动窗口中第x个数是负数还是其他。*我刚开始想要哈希表,但似乎哈希表无法表示第x个数这种顺序性,于是只想到用应该二维数组,来存储每一个窗口的所有值,然后再对每一个窗口排序,这样很明显10^5 10 ^ 5是超空间的。
但我疏忽的一点是题目上给出数组中的元素值是范围是很小的,因此我们可以用计数排序的思想,循环遍历所有可能会出现的负数元素值,看它会不会出现在滑动窗口的哈希表中,如果哈希表中存在x个负数,就说明美丽值是存在的,反之为0.这句话用代码表示即为下面:
int cnt=0;for(int i=-50;i<0;i++){if(mp.count(i)){cnt+=mp[i];}if(cnt>=x){ans.push_back(i);break;}}if(cnt<x){ans.push_back(0);}
完整代码如下:
class Solution {
public:vector<int> getSubarrayBeauty(vector<int>& nums, int k, int x) {vector<int> ans;unordered_map<int,int> mp;int l=0;int r=l+k-1;int n=nums.size();for(int i=0;i<0+k;i++){mp[nums[i]]++;}int cnt=0;for(int i=-50;i<0;i++){if(mp.count(i)){cnt+=mp[i];}if(cnt>=x){ans.push_back(i);break;}}if(cnt<x){ans.push_back(0);}mp[nums[l]]--;if(mp[nums[l]]==0){mp.erase(nums[l]);}l++;for(int i=k;i<n;i++){mp[nums[i]]++;cnt=0;if(i-l+1==k){for(int j=-50;j<0;j++){if(mp.count(j)){cnt+=mp[j];}if(cnt>=x){ans.push_back(j);break;}}if(cnt<x){ans.push_back(0);}mp[nums[l]]--;if(mp[nums[l]]==0){mp.erase(nums[l]);}l++;}}return ans;}
};
时间复杂度为O(n*常数)约等于O(n)。