今天接触到了链表的相关知识,重温和巩固了一下链表这一数据结构的知识储备。
203、移除链表元素
题目链接:203. 移除链表元素 - 力扣(LeetCode)
class Solution {
public:
ListNode* removeElements(ListNode* head, int val) {
ListNode* cur=new ListNode(0);
cur->next=head;
ListNode* point=cur;
while(point!=nullptr&&point->next!=nullptr)
{
if(point->next->val==val)
{
ListNode* temp=point->next;
point->next=point->next->next;
delete temp;
}
else
{
point=point->next;//这里比较精妙,当你删除完一个节点后,你需要停在原地,然后对新的下一个节点要进行判断,而不能直接跳过
}
}
head=cur->next;
return head;
}
};
一个简单的链表删除。需要注意的地方一个是边界的判断,不能出现空的节点;二是删除完节点后需要对新的节点判断而不能直接跳过。不得不说虚拟头结点确实可以省去很多的麻烦。
707.设计链表
class MyLinkedList {
public:
struct LinkNode
{
int val;
LinkNode* next;
LinkNode(int val):val(val),next(nullptr){}
};
MyLinkedList() {
cur=new LinkNode(0);
size=0;
}
int get(int index) {
if(size==0||index>=size) return -1;
//else if (size == 1) return cur->next->val;
else
{
LinkNode* point=cur;
index++;
while(index--)
{
point=point->next;
}
return point->val;
}
}
void addAtHead(int val) {
LinkNode* newnode=new LinkNode(val);
if(cur->next==nullptr) cur->next=newnode,size++;
else
{
newnode->next=cur->next;
cur->next=newnode;
size++;
}
}
void addAtTail(int val) {
LinkNode* newnode=new LinkNode(val);
if(size==0)
{
cur->next=newnode;
}
else
{
LinkNode* point=cur;
while(point!=nullptr&&point->next!=nullptr)
{
point=point->next;
}
point->next=newnode;
}
size++;
}
void addAtIndex(int index, int val) {
if(index>size) return;
else
{
LinkNode* newnode=new LinkNode(val);
LinkNode* point=cur;
while(index--)
{
point=point->next;
}
newnode->next=point->next;
point->next=newnode;
size++;
}
}
void deleteAtIndex(int index) {
if(index>=size) return;
else
{
LinkNode* point=cur;
int x=index--;
while(x--)
{
point=point->next;
}
LinkNode* temp=point->next;
if(temp!=nullptr) point->next=point->next->next;
else point->next=nullptr;
delete temp;
size--;
}
}
private:
int size=0;
LinkNode* cur;
};
/**
* Your MyLinkedList object will be instantiated and called as such:
* MyLinkedList* obj = new MyLinkedList();
* int param_1 = obj->get(index);
* obj->addAtHead(val);
* obj->addAtTail(val);
* obj->addAtIndex(index,val);
* obj->deleteAtIndex(index);
*/
这个题就是自主设计一个链表类,涉及到添加头结点、添加中心节点、添加尾节点、将新节点插入特定位置、删除节点、查询节点等基本操作。边界判断挺多的,不容易过,需要温习。
206.反转链表
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode() : val(0), next(nullptr) {}
* ListNode(int x) : val(x), next(nullptr) {}
* ListNode(int x, ListNode *next) : val(x), next(next) {}
* };
*/
class Solution {
public:
ListNode* reverseList(ListNode* head) {
ListNode* pre=nullptr;
ListNode* cur=head;
ListNode* temp;
while(cur!=nullptr)
{
temp=cur->next;
cur->next=pre;
pre=cur;
cur=temp;
}
return pre;
}
};
反转链表也是用到了双指针的算法思想,通过记录后面的节点来完成交替的赋值,从而实现没有新开空间的条件下实现链表翻转,挺有意思的。
总结
昨天由于有点事没打卡,今天早上牺牲了健身时间补上了,感觉开始上难度了,希望可以适应这样的节奏。