题目链接92. 反转链表 II - 力扣(LeetCode)
这次属于题目优化的思路
常规思路就是切断链表,然后进行整个反转操作,这里面就只需要注意链表的节点获取问题
而穿针引线的方法只需要遍历一次链表,比较考验对链表操作的理解,多指针的情况下,很容易造成线断掉的情况
细节如下
/** * 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: //利用链表的切割来做来着 //找到切割链表的点大概是,链表的left的前一个和right的后一个 void reverse(ListNode* head){ ListNode *pre=nullptr; ListNode *cur=head; ListNode *temp; while(cur!=nullptr){ //temp要在里面一开始定义,避免发生,temp在最后cur->next最后出现空指针异常的情况 temp=cur->next; cur->next=pre; pre=cur; cur=temp; } } ListNode* reverseBetween(ListNode* head, int left, int right) { //定义虚拟头结点,避免讨论 ListNode* dummyHead=new ListNode(-1); dummyHead->next=head; //1.找到需要翻转链表的范围 ListNode *Left; ListNode *Right; int cntleft=0; int cntright=0; //定义一个节点指针 ListNode *cur=dummyHead; ListNode* pre; //就是问题所在你需要找到的其实是链表left的前一个节点,以及right节点,所以说要注意范围 while(cntleft!=left-1){ cur=cur->next; cntleft++; cntright++; } pre=cur; //好像没啥用left=pre->next; while(cntright!=right){ cur=cur->next; cntright++; } Right=cur; //2.开始穿针 ListNode *after=pre->next; cur=after->next; for(int i=1;i<=right-left;i++){ after->next=cur->next; cur->next=pre->next; pre->next=cur; cur=after->next; } return dummyHead->next; } };
注意的是指针一般不能按来做比较,因为指向的是地址
并且一定注意操作次数以及空指针的问题
知道操作次数,最好还是用for循环比较好拉
也并不是,因为,其实是right的值在最后改变了
所以链表一定要尤其注意空指针的问题
在链表的节点改变之后,相应的会引发一系列连锁反应
双指针法的应用
/**
* 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* removeNthFromEnd(ListNode* head, int n) {
//删除节点需要对头部操作所以不用想都知道需要用到虚拟头结点
ListNode *dummyHead=new ListNode(-1);
dummyHead->next=head;
//本题采用双指针的方法,采用快慢指针的思路进行操作
//先让快指针运动n次再让慢指针动,直到慢指针运动到结尾就可以
ListNode* fast=dummyHead;
ListNode* slow=dummyHead;
while(n--){
fast=fast->next;
}
while(fast!=NULL&&fast->next!=NULL){
fast=fast->next;
slow=slow->next;
}
slow->next=slow->next->next;
return dummyHead->next;
}
};
小心空指针就可以