LeetCode24两两交换链表中的节点
思路:两两交换链表的节点我一开始并未想到增加 虚拟头结点导致出现了问题,后来通过查看代码随想录中的讲解,直观了理解了这道题的步骤,同时发现了画图在做题中的重要性。
/**
* 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* swapPairs(ListNode* head) {
ListNode* dummyhead=new ListNode(0);
dummyhead->next=head;
ListNode* cur=dummyhead;
while(cur->next!=nullptr&&cur->next->next!=nullptr)
{
ListNode* tmp=cur->next;
ListNode* tmp1=cur->next->next->next;
cur->next=cur->next->next;
cur->next->next=tmp;
cur->next->next->next=tmp1;
cur=cur->next->next;
}
return dummyhead->next;
}
};
本题理清楚三个步骤就很简单了。
LeetCode19删除链表中倒数第N个节点
思路:这道题一开始没有想到使用双指针法,所以在倒数第N个的确定上有些障碍,我想先遍历一下链表求出链表长度然后减N就可以正向删除相应的节点。当然也可以使用双指针法。
计算长度:
class Solution {
public:
ListNode* removeNthFromEnd(ListNode* head, int n) {
ListNode* dummyhead=new ListNode(0);
dummyhead->next=head;
ListNode* fast=dummyhead;
ListNode* slow=dummyhead;
int count=0;
while(fast->next!=nullptr){
fast=fast->next;
count++;
}
count=count-n;
while(count--&&slow->next!=nullptr&&slow!=nullptr){
slow=slow->next;
}
slow->next=slow->next->next;
return dummyhead->next;
}
};
双指针法:
class Solution {
public:
ListNode* removeNthFromEnd(ListNode* head, int n) {
ListNode* dummyhead=new ListNode(0);
dummyhead->next=head;
ListNode* slow=dummyhead;
ListNode* fast=dummyhead;
while(n--&&fast->next!=nullptr){
fast=fast->next;
}
fast=fast->next;
while(fast!=nullptr){
fast=fast->next;
slow=slow->next;
}
slow->next=slow->next->next;
return dummyhead->next;
}
};
面试题0207链表相交
思路:一开始我并没有理解链表相交的意思,我以为有一个交点即可,剩下的节点仍然可以不同,理解错了题意。如果两个链表有公共的节点,那么从第一个公共的节点开始,剩下的节点都是相同的。而且需要注意的是值相同并不等于节点相同。
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
ListNode* curA = headA;
ListNode* curB = headB;
int lenA = 0, lenB = 0;
while (curA != NULL) { // 求链表A的长度
lenA++;
curA = curA->next;
}
while (curB != NULL) { // 求链表B的长度
lenB++;
curB = curB->next;
}
curA = headA;
curB = headB;
if (lenB > lenA) {
swap (lenA, lenB);
swap (curA, curB);
}
// 求长度差
int gap = lenA - lenB;
// 让curA和curB在同一起点上(末尾位置对齐)
while (gap--) {
curA = curA->next;
}
// 遍历curA 和 curB,遇到相同则直接返回
while (curA != NULL) {
if (curA == curB) {
return curA;
}
curA = curA->next;
curB = curB->next;
}
return NULL;
}
};
LeetCode142环形链表||
思路:这道题难度较大,重点在于快慢指针的速度设置以及判断环的入口点。
借鉴代码随想录的思想
class Solution {
public:
ListNode *detectCycle(ListNode *head) {
ListNode* fast=head;
ListNode* slow=head;
while(fast!=NULL&&fast->next!=NULL){
slow=slow->next;
fast=fast->next->next;
if(slow==fast){
ListNode* index1=fast;
ListNode* index2=head;
while(index1!=index2){
index1=index1->next;
index2=index2->next;
}
return index2;
}
}
return NULL;
}
};
总结:到今天链表的章节结束了,在链表的题目中,双指针法十分重要,同时画图可以更好的帮助理解题目要求和内容,以后要养成做提前画图的习惯。最后一道环形链表的题目需要多看看,加深理解。