问题分析:
题目的内容易于理解,为从一个固定的窗口中找到其中位数,我们要完成的任务是维护一个有序的子序列,如果直接排序的话会超时,可以想到每次其实只是增加了一个元素与删除了一个元素而已
step1 : 找到已经排好序的数组里的要删除的元素进行删除操作
step2:将新插入的元组插入到有序数组中
代码1
class Solution {
public:
vector<double> medianSlidingWindow(vector<int>& nums, int k) {
vector<double> res;
multiset<double> st;
for (int i = 0; i < nums.size(); ++i) {
if (st.size() >= k) st.erase(st.find(nums[i - k]));
st.insert(nums[i]);
if (i >= k - 1) {
auto mid = st.begin();
std::advance(mid, k / 2);
res.push_back((*mid + *prev(mid, (1 - k % 2))) / 2);
}
}
return res;
}
};
注意:
advance: advance(it, n) it 表示某个迭代器,n 为整数。该函数的功能是将 it 迭代器前进或后退 n 个位置。
prev(it) it 为指定的迭代器,该函数默认可以返回一个指向上一个位置处的迭代器。注意,it 至少为双向迭代器。
my_code
class Solution {
public:
vector<double> medianSlidingWindow(vector<int>& nums, int k) {
vector<double> res;
vector<int> temp(nums.begin(),nums.begin()+k);
sort(temp.begin(),temp.end());
if(k%2==0)
{
res.push_back(double(long(temp[k/2])+long(temp[(k-1)/2]))/2);
}
else
{
res.push_back(temp[k/2]);
}
for (int i = k; i < nums.size(); ++i) {
int re = 0;
for(re = 0;re<temp.size();re++)
{
if(temp[re]==nums[i-k])
{
break;
}
}
temp.erase(temp.begin()+re);
int ins = 0;
for(ins = 0;ins<temp.size();ins++)
{
if(temp[ins]>=nums[i])
{
break;
}
}
temp.insert(temp.begin()+ins,nums[i]);
if(k%2==0)
{
res.push_back(double(long(temp[k/2])+long(temp[(k-1)/2]))/2);
}
else
{
res.push_back(temp[k/2]);
}
}
return res;
}
};
滑动窗口双指针同向移动模板:
for(int right;right<n;right++)
{
cnt[s[right]];
while(check(cnt))
{
left++;
}
}
lenght = right - left + 1; //记录与处理
K 个不同整数的子数组
思路详解: 答案很妙,直接将其恰好转化成了最多,并且用right-left表示了数目,模板还是那个模板,注意right在最后记录之前就++了,所以是一个开区间,最后不用+1
代码:
public class Solution {
public int subarraysWithKDistinct(int[] A, int K) {
return atMostKDistinct(A, K) - atMostKDistinct(A, K - 1);
}
/**
* @param A
* @param K
* @return 最多包含 K 个不同整数的子区间的个数
*/
private int atMostKDistinct(int[] A, int K) {
int len = A.length;
int[] freq = new int[len + 1];
int left = 0;
int right = 0;
// [left, right) 里不同整数的个数
int count = 0;
int res = 0;
// [left, right) 包含不同整数的个数小于等于 K
while (right < len) {
if (freq[A[right]] == 0) {
count++;
}
freq[A[right]]++;
right++;
while (count > K) {
freq[A[left]]--;
if (freq[A[left]] == 0) {
count--;
}
left++;
}
// [left, right) 区间的长度就是对结果的贡献
res += right - left;
}
return res;
}
}