https://leetcode.cn/problems/remove-linked-list-elements/description/
因为是不带表头的,所以要区分两种情况,第一种是要删除的链表元素就是表头的元素,这里假设有多个要删除的元素,所以应该是while(head!=NULL&&head->val==val)用的是while循环的方式,而不是If的形式,只要head的值等于val,那么head就不断往后移动;第二种是要删除的元素不是表头的元素,那么这时候只要让cur的指针移动到要删除元素的头一个节点,temp=cur->next(temp代表要删除的节点),cur->next=temp->next,就可以实现删除的效果。
注意,在判断完第一种条件后,还需要判断head是否为空才可以直接进入下一种情况,这时候下一种情况的判断条件是while(cur->next!=NULL)。如果判断head是否为空,那判断条件就要写成while(head!=NULL&&head->next!=NULL)。循环完,要记得返回head节点。
这种方法要求我们自己先设置一个表头结点dummyHead,dummyHead->next=head,用这种方法主要是为了方便统一,如果用这种方法,就不需要判断不带表头法所需要的两种情况,因为有了咱们自己定义的表头结点,其他所有要删除的元素都属于带表头法的第二种情况了。
class Solution {
public:
ListNode* removeElements(ListNode* head, int val) {
//不带头结点法
// ListNode*temp1;
// while(head!=NULL&&head->val==val)
// { temp1=head;
// head=head->next;
// delete temp1;
// }
// if (head==NULL) return head;
// ListNode*cur=head;
// ListNode*temp2;
// while(cur->next!=NULL)
// {
// if(cur->next->val==val)
// {
// temp2=cur->next;
// cur->next=temp2->next;
// delete temp2;
// }
// else
// {
// cur=cur->next;
// }
// }
// return head;
//带头结点法
ListNode*dummyHead=new ListNode(0);
dummyHead->next=head;
ListNode*cur=dummyHead;
while(cur->next!=NULL)
{
if(cur->next->val==val)
{
ListNode*temp=cur->next;
cur->next=temp->next;
delete temp;
}
else
{
cur=cur->next;
}
}
head=dummyHead->next;
delete dummyHead;
return head;
}
};
初始化链表的时候我们用的是带表头结点的方法,方便后序的统一。同时,要将size设置为0.
通过传入参数Index,index表示第index个节点(注意,是从节点0开始的),要找到对应的元素值,首先要对index进行判断,如果indez<0||index>size(因为是从节点0开始的,所以应该是>size),return -1(表示找不到);如果index合法,就设置cur=dummyHead->next,(这里设置为->next是让它直接指向第0个节点,因为咱们是根据index的值判断的,index=0表示移动0次,那么这时候跟我们设置的就符合,然后如果index=1,就在原来的基础上向右移动一位,依此类推。
通过传入参数val表示要插入的节点的值,这是一个从表头插入的方法,所以直接new一个节点newNode,newNode->next=dummyHead->next;dummyHead->next=newNode即可。
通过传入参数val表示要插入的节点的值,然后找到链表的最后一个节点,在节点后面添加值为val的节点,具体是设置cur=dummyHead(这里不设置为head->next是因为咱们要找的是插入位置的前一个节点而不是插入位置),while(cur->next!=NULL),cur就会不断移动直到cur->next==NULL,这时候的cur就是末尾的节点。
这个跟Get函数很像但有区别,Get函数是找index位置的值,而deleteAtIndex则是删除index位置的节点,所以Get的初始化是cur=dummyHead->next;while(index--);而deleteAtIndex则是初始化cur=dummyHead;while(index--),因为我们要找的是delete掉的节点的前一个节点,这样才能删除要被删除的节点。同时也要注意判断index是否合法。
其实就是让指针从真正有值的第一个节点开始(也就是dummyHead的下一个节点)移动到最后一个节点,输出值即可。
class MyLinkedList {
public:
MyLinkedList() {
dummyHead=new LinkedNode(0);
size=0;
}
int get(int index) {
if(index<0||index>=size)
{
return -1;
}
LinkedNode*cur=dummyHead->next;
while(index)
{
cur=cur->next;
index--;
}
return cur->val;
}
void addAtHead(int val) {
LinkedNode*newNode=new LinkedNode(val);
newNode->next=dummyHead->next;
dummyHead->next=newNode;
size++;
}
void addAtTail(int val) {
LinkedNode*cur=dummyHead;
while(cur->next!=NULL)
{
cur=cur->next;
}
LinkedNode*newNode=new LinkedNode(val);
cur->next=newNode;
size++;
}
void addAtIndex(int index, int val) {
if(index>size) return;
if(index<0) index=0;
LinkedNode*cur=dummyHead;
while(index)
{
cur=cur->next;
index--;
}
LinkedNode*newNode=new LinkedNode(val);
newNode->next=cur->next;
cur->next=newNode;
size++;
}
void deleteAtIndex(int index) {
if(index<0||index>=size)
return;
LinkedNode*cur=dummyHead;
while(index--)
{
cur=cur->next;
}
LinkedNode*temp=cur->next;
cur->next=temp->next;
delete temp;
temp=NULL;
size--;
}
private:
LinkedNode*dummyHead;
int size;
};
https://leetcode.cn/problems/reverse-linked-list/submissions/495429721/
定义一个pre指针,注意pre指针初始化是NULL,因为第一个节点反转的话,指向的节点是空的,定义一个cur指针,让cur->next=pre,然后让pre和cur都往后移动,循环让cur->next=pre即可。注意在这个过程中还要设置一个临时指针变量来存储cur->next,这样cur才能移动到下一个位置,不然cur->next=pre这一步会使cur丢失掉它原本指向的下一个位置。
递归法的第一种和双指针法的思路是差不多的,通过传入参数pre,cur,然后tmp=cur->next,cur->next=pre,然后不断调用该函数,下一次函数传入的值的pre是现在执行的这个函数的cur,传入的cur的值是现在执行函数的tmp,不断调用直到cur==NULL为止。
递归法2是先走到最后一个节点,然后再调整,而递归法1是先调整,再走到最后一个节点。递归法2是一上来就调用reverseList,直到到达最后一个节点,再从最后一个节点的前一个节点开始反转,直到走回到链表原本的头结点。
class Solution {
public:
ListNode*reverse(ListNode*pre,ListNode*cur)
{
if(cur==NULL)
return pre;
ListNode*temp=cur->next;
cur->next=pre;
return reverse(cur,temp);
}
ListNode* reverseList(ListNode* head) {
//非递归
// ListNode*pre=NULL;
// ListNode*cur=head;
// while(cur)
// {
// ListNode*tmp=cur->next;
// cur->next=pre;
// pre=cur;
// cur=tmp;
// }
// return pre;
// }
//递归1
// if(head==NULL||head->next==NULL)
// return head;
// ListNode*newHead=reverseList(head->next);
// head->next->next=head;
// head->next=NULL;
// return newHead;
// }
//递归二
return reverse(0,head);
}
};