首页 > 编程语言 >代码随想录算法训练营Day5 数组、链表复习

代码随想录算法训练营Day5 数组、链表复习

时间:2023-02-05 21:12:54浏览次数:37  
标签:index val int Day5 随想录 next 链表 节点

数组部分

数组最重要的思维方式是双指针的使用。

快慢指针

在进行元素移除和元素操作时会使用两个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

相关文章