1.滑动窗口
窗口平移,保留长度信息
int r=-1,l=0;
while(r<n-1){
//l-r间状态信息
nums[r+1]
if(//不满足状态){
//更新l-r状态
l++;
}
r++;
}
return r-l+1
窗口不平移,跳跃更新
int l=-1,r=0;
while(r<n){
nums[r]
if(//不满足条件){
l=r;
}
r++;
}
总结
窗口平移和不平移的细微区别在于l和r的初始值设置。
对于窗口平移,保留长度信息的来讲,l=0,r=-1。
窗口不平移的 l=-1,r=0
2. 并查集
图的连通性,字符串交换性,去除图的冗余连接,连接所有点的最小费用(kruscal)
//路径压缩版本,所有共同父节点的节点,都会直连在父节点
int Find(vector<int>& parent, int index){
if(index == parent[index]){
return index;
}else{
parent[index] = Find(parent,paretn[index]);
return parent[index];
}
}
//非路径压缩版本
int Find(vector<int>& parent, int index){
while(index != parent[index]){
index = parent[index];
}
return index;
}
vodi Union(vector<int>& parent, int index1,int index2){
parent[Find(index1)] = Find(index2);
}
//最重要的,parent的初始化
for(int i = 0; i < n; i++){
parent[i] = i;
}
3.双链表操作
pt构建法,进到while循环就先创建t节点,让p指向t,但这样构造出来的链表最后总会多出来一个末尾节点。
struct ListNode{
int val;
ListNode* next;
ListNode():val(0),next(nullptr){}//必须定义
};
ListNode* twoList(ListNode &l1, ListNode &l2){
ListNode *res,*p;
p = new ListNode();
res = p;
while(l1&&l2){
ListNode*t = new ListNode();
p->next = t;
//更多对p->val的操作
p = t;
l1 = l1->next;
l2 = l2->next;
}
while(l1){
ListNode*t = new ListNode();
p->next = t;
//更多对p->val的操作
p = t;
l1=l1->next;
}
while(l2){
ListNode*t = new ListNode();
p->next = t;
//更多对p->val的操作
p = t;
l2=l2->next;
}
return res;
}
4.图的深度遍历法
//从vec开始遍历,因为图可能是不连通的,因此需要从不同的vec开始出发遍历
//对visited的操作能够判断图的连通性,效果不如并查集
for(int i =0; i < matrix.size(); i ++){
traverse(matrix,visited,i);
}
void traverse(vector<vector<int>>&matrix,vector<int>&visited,int vec){
if(visited[vec] == 1) return ;
visited[vec] = 1;
for(int i = 0; i < matrix.size(); i ++){
if(visited[i]==0) traverse(matrix,visited,i);
}
}