算法笔记
vector操作
vector的修改需要预先分配内存
//例1
int main()
{
vector<int> num(10);//预先分配内存
num[0] = 1;
num[1] = 2;
return 0;
}
//例2
int main()
{
vector<int> num(10);
vector<int>num_1(num);//用num初始化构造num_1
num_1[0] = 1;
num_1[1] = 2;
return 0;
}
//例3
int main()
{
int test[] = { 1,2,3,4,5 };
vector<int> num(test, test + 2);// 1 2
num[0] = 1;
num[1] = 2;
return 0;
}
分配内存后可以通过下标修改元素
可以使用 v.resize(v.size()) 给没有预分配内存的容器分配内存,此方法不会改变容器元素,只改变capacity,resize超过原大小的默认值为0
- v[0]=1;
- v.at[1]=3;
- v.assign(n,val)
v.assign(n,val) 和vector的初始化v(n,val)一样,分配n个元素,值为val,
如果已经预分配,且n小于原来的size,则不会改变capacity,只会改变size
如果大于原来的size,则会capacity和size都会变
| v.pop_back(); | 删除尾末元素,无返回值 |
| v.push_back(val) | 尾末压入val元素 |
| v.clear() | 清空容器 |
| v.insert(it,val) | 在迭代器IT位置插入元素val |
|---|---|
| v.insert(it,n,val) | 在it处插入n个val元素 |
| v.insert(it,{val1,val2,val3…..}) | 在it处插入元素val1,val2,val3….. |
| v.erase(it) | 删除迭代器it处的元素 |
|---|---|
| v.erase(it1,it2) | 删除【it1,it2)处的所有元素—左闭右开 |
| reverse(it1,it2) | 将【it1,it2)内的元素倒置 |
|---|---|
| copy(v1.begin,v1.end(),v2.begin()) | 将v1的【begin,end)复制到v2,从v2的begin处开始覆盖 |
|---|---|
| it=find(v.begin(),v.end(),k) | 在【begin,end)中查找元素k,成功则返回指向k处的迭代器;失败则返回end |
|---|---|
滑动窗口
滑动窗口也可以理解为双指针法的一种!只不过这种解法更像是一个窗口的移动,所以叫做滑动窗口更适合一些。
在本题中实现滑动窗口,主要确定如下三点:
- 窗口内是什么?
- 如何移动窗口的起始位置?
- 如何移动窗口的结束位置?
一般会会写在两个循环中,通常只会让一边(左边或右边)在外层循环前进,内层循环边做判断边推进,看起来像是一边推进一次,另外一边处理一次。

class Solution {
public:
int minSubArrayLen(int target, vector<int>& nums) {
int count=0,sum=0;
int i=0,j=0;
while(1){
while(sum<target&&j<nums.size()){//向右扩大窗口直到满足条件
sum+=nums[j];
j++;
}
if(sum<target) return count;//已经不能再扩
if(count==0) count=j-i;//第一次扩的时候把count初始化一个长度
else count=count<(j-i)?count:(j-i);//最小子串
sum-=nums[i];//缩小窗口,每一次缩小都可能会破坏满足条件,所以会再进入上面循环扩大窗口
i++;
}
return count;
}
};
前缀和
前缀和的思想是重复利用计算过的子数组之和,从而降低区间查询需要累加计算的次数。
前缀和 在涉及计算区间和的问题时非常有用!


p 数组是我们之前就计算好的累加和,所以后面每次求区间和的之后 我们只需要 O(1) 的操作。
特别注意: 在使用前缀和求解的时候,要特别注意 求解区间。
如上图,如果我们要求 区间下标 [2, 5] 的区间和,那么应该是 p[5] - p[1],而不是 p[5] - p[2]。
评论

