数组部分
数组最重要的思维方式是双指针的使用。
快慢指针
在进行元素移除和元素操作时会使用两个for循环嵌套,此时时间复杂度为O(n²)。在for循环中通过双指针(快慢指针)的使用可以使时间复杂度将为O(n)。
快慢双指针的定义:
int slowIndex=0;int fastIndex=0;
for(fastIndex=0;fastIndex<nums.size();fastIndex++){
}
相向双指针
在进行元素移除操作时,如果采用相向双指针的操作,可以基于元素顺序改变元素的相对位置,确保了移动最少元素。
相向双指针的定义:
int leftIndex=0;
int rightIndex=nums.size()-1;//定义的时Index下标,所以要size()-1
while(leftIndex<=rightIndex){
while(leftIndex<=rightIndex&&nums[leftIndex]!=val){//找左边等于val的元素
++leftIndex;
}
while(rightIndex>=leftIndex&&nums[rightIndex==val){//找右边不等于val的元素
--rightIndex;
}
if(leftIndex<rightIndex){//将右边不等于val的元素覆盖左边等于val的元素
nums[leftIndex++]=nums[rightIndex--];
}
}
滑动窗口
在双指针移动过程中主要关注两指针中间的元素值之和时,即可成为滑动窗口问题,滑动窗口的关键在于窗口初始、终止位置的移动。
代码实现:
while(sum>=s){
subLength=(j-i+1);//取子序列的长度
result=result<subLength?result:sublength;//比较result和subLength的长度,当a<b?为1时,result = result,为0时,result=sbuLength
sum-=nums[i++];//这里体现滑动窗口的精髓之处,不断变更i(子序列的起始位置)
}
注意:※ c=a<b?a:b
是三元运算符,是将ab中较小的值赋给c,等同于
if(a<b){c=a;}
else {c=b;}
螺旋矩阵
螺旋矩阵的实现只能通过4个for循环进行模拟实现,处理规则为循环不变量,在最外层通过while控制每圈的循环,在每层内通过for进行每行、列的赋值。每列的取值是左开右闭区间。
链表部分
链表是由指针串联在一起的线性结构,每个节点由一个数据域和一个指针域组成。
设计链表
设计链表是leetCode中对链表整理最丰富的题目
定义链表结构体:
struct LinkedNode{
int val;
LinkedNode* next;
LinkedNode(int val):val(val),next(nullptr){}
};
初始化链表:
MyLinkList(){
_dummyNode=new LinkedNode(0);//初始化虚拟头节点
_size=0;
}
获取第index个节点数值,如果是非法则返回-1,第0个是头节点
get:
int get(int index){
if(index>(_size -1)||index<0){
retrun-1;
}
LinkNode* cur=_dummyHead->next;//定义一个新的节点为虚拟头节点的下一个
while(index--){
cur=cur->next;
}
return cur->val;
}
在链表前插入节点,插入后的节点为新的头节点
void addAtHead(int val){
LinkedNode* newNode=new LinkedNode(val);
newNode->next=_dummyHead->next;
_dummyHead->next=newNode;
_size++;
}
在链表后加一个节点
void addAtTail(int val){
LinkNode* newNode=new LinkedNode(val);
newNode->next=_dummyNead->next;
_dummyHead->next=newNode;
_size++;
}
在第index个节点前插入新节点,如果index等于链表长度,说明新节点为链表尾节点;index大于链表长度,则返回空;index小于0,则在头部插入节点
void addIndex(int index,int val){
if(index>_size) return;
if(index<0) index=0;
LinkedNode* newNode=new LinkedNode(val);
LinkedNode* cur=_dummyHead;
while(index--){
cur=cur->next;
}
newNode->next=cur->next;
cur->next=newNode;
_size++;
}
删除第index个基点,如果index大于等于链表的长度,直接return,index是从0开始
void deleteAtIndex(int index){
if(index>=_size||index<0){
return;
}
LinkedNode* cur=_dummyHead;
while(index--){
cur=cur->next;
}
LinedNode* tmp=cur->next;
cur->next=cur->next->next;
delete tmp;
_size--;
}
打印链表
void printLinkedList(){
LinkedNode* cur=_cummyHead;
while(vur->next!=nullptr){
.cout<<cur->next->val<<".";
vur=cur->next;
}
cout<<endl;
}
链表的虚拟头节点
虚拟头节点是链表操作中非常重要的方法
虚拟头节点的建立:
ListNode* dummyHead=new ListNode(0);
dummyHead->next=head;//虚拟头节点指向head,方便后续删除操作
链表的域表示
head->val
是指head节点的val(data)值域
head->next
是指head节点的next 指针域
head->next->next
是指head节点后面的第二个节点,head->next
是后面第一个
C++语言的基本知识
交换语法
swap(a,b)
交换a、b,时间复杂度为O(nlog2n)
三元运算符
※ c=a<b?a:b
是三元运算符,是将ab中较小的值赋给c,等同于
if(a<b){c=a;}
else {c=b;}
C++语言规范
#include<iostream>
using namespace std;
int main(){}
vector容器(可用于定义数组)
#inlude<vector>
using namespace std;
int main(){
vector<int>& a;
}
标签:index,val,int,Day5,随想录,next,链表,节点
From: https://www.cnblogs.com/bailichangchuan/p/17093941.html