该题通过构建虚拟头结点对链表进行遍历,遍历过程中删除值为val的结点。
具体代码如下:
class Solution {
public:
ListNode* removeElements(ListNode* head, int val) {
ListNode*p=new ListNode(0);
ListNode*tmp=p;
p->next=head;
while(p!=NULL&&p->next!=NULL)
{
if(p->next->val==val)
{
ListNode*q=p->next;
p->next=q->next;
delete q;
}
else
{
p=p->next;
}
}
return tmp->next;
}
};
该题要求反转链表,起初我想到的办法是将给定链表遍历并用头插法进行建表,但这样会占据额外的内存空间,这里介绍第二种方法:运用两个指针,一个指针指向前驱结点,一个指针指向后继结点,而后将前驱和后继结点进行反转,再将两个指针向后移动,直到遍历完整个链表。
具体代码如下:
class Solution {
public:
ListNode* reverseList(ListNode* head) {
ListNode* prearc=NULL;
ListNode* nextarc=head;
while(nextarc!=NULL)
{
ListNode*p=nextarc->next;
nextarc->next=prearc;
prearc=nextarc;
nextarc=p;
}
return prearc;
}
};
本题是对链表的构建,每一个函数都较为简单,但在构建时要注意虚拟头结点的建立以及链表的大小对查询时是否越界的影响。
具体代码如下:
class MyLinkedList {
private:
ListNode*head;
int size;
public:
MyLinkedList() {
this->head=new ListNode(0);
this->size=0;
}
int get(int index) {
if(index<0||index>=size)
{
return -1;
}
int n=-1;
ListNode* p=head;
while(n<index)
{
p=p->next;
n++;
}
return p->val;
}
void addAtHead(int val) {
ListNode*p=new ListNode(val);
p->next=head->next;
head->next=p;
size++;
}
void addAtTail(int val) {
ListNode*p=new ListNode(val);
ListNode*q=head;
while(q->next!=NULL)
{
q=q->next;
}
q->next=p;
size++;
}
void addAtIndex(int index, int val) {
if(index>size)
{
return;
}
ListNode*p=new ListNode(val);
ListNode*q=head;
int n=-1;
while(n<index-1)
{
q=q->next;
n++;
}
p->next=q->next;
q->next=p;
size++;
}
void deleteAtIndex(int index) {
if(index<0||index>=size)
{
return;
}
int n=-1;
ListNode*p=head;
while(n<index-1)
{
p=p->next;
n++;
}
ListNode*q=p->next;
p->next=q->next;
delete q;
size--;
}
};