24. 两两交换链表中的节点
知识点:链表 状态:15分钟憋出来了
思路:先创造一个虚拟头节点,每两个节点一换,再移动两个,temp3存的是所交换的两个节点的下一个(所以是3),同理temp1是第一个节点
注意:while循环条件光写cur->next->next!=null忘写 cur->next!=null了
/**
* 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 * dummynode = new ListNode(0);
dummynode->next = head;
ListNode * cur = dummynode;
while( cur -> next != NULL && cur -> next -> next != NULL )
{
ListNode* temp3 = cur -> next -> next-> next ;
ListNode* temp1 = cur -> next ;
cur->next = cur->next->next;
cur->next->next = temp1;
temp1->next = temp3;
cur = cur -> next -> next;
}
return dummynode -> next;
}
};
19.移除链表元素
知识点:链表 状态:写出来两次遍历,双指针看解析做出来的
思路:还是先创造一个虚拟头节点,当删除倒数第n个数时,指针肯定是要指向倒数第n+1个数前面才方便修改。具体实现是:快慢指针,都从虚拟头结点开始,先让fast移动n个,然后再同时移动fast话日slow,当fast=null时,slow正好指向那个数,但无法进行删除操作了,所以需要先让fast移动n+1个即可。
注意:应返回 dummynode->next而不是head,因为head所指向的节点可能被删除了。
/**
* 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 * dummynode = new ListNode(0);
dummynode->next = head;
ListNode * fast = dummynode;
ListNode * slow = dummynode;
while( n--&& fast != NULL )
{
fast=fast->next;
}
fast= fast->next;
while( fast != NULL)
{
slow=slow->next;
fast=fast->next;
}
slow->next = slow->next->next;
return dummynode->next;
}
};
160.链表相交
知识点:链表 ,双指针、哈希 状态:之前做过
思路:两条链表,第一条链表遍历完后遍历第二条,第一条链表遍历完后遍历第二条,这两个指针会在相交点相等。
注意:三目运算符妙啊
/**
* 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) {
if (headA == nullptr || headB == nullptr) {
return nullptr;
}
ListNode *pA = headA, *pB = headB;
while (pA != pB) {
pA = pA == nullptr ? headB : pA->next;
pB = pB == nullptr ? headA : pB->next;
}
return pA;
}
};
141.环形链表
知识点:链表 快慢针指针 状态:之前做过,细节扣的不准
思路:直接复制官方题解了,很妙
我们使用两个指针,fast 与 slow。它们起始都位于链表的头部。随后,
slow指针每次向后移动一个位置,而 fast 指针向后移动两个位置。如果链表中存在环,则
fast指针最终将再次与 slow 指针在环中相遇。
如下图所示,设链表中环外部分的长度为 a。slow 指针进入环后,又走了 b 的距离与
fast 相遇。此时, 指针已经走完了环的 n 圈,因此它走过的总距离为
a+n(b+c)+b=a+(n+1)b+nc。(从2(a+b) = a+b+n(b+c) 推到过去的)
来源:力扣(LeetCode)
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode *detectCycle(ListNode *head)
{
ListNode * slow = head;
ListNode * fast = head;
while(fast != NULL && fast->next != NULL)
{
fast = fast->next->next;
slow = slow->next;
if ( fast == slow )
{
slow= head;
while (slow != fast)
{
fast = fast->next;
slow = slow->next;
}
return slow;
}
}
return NULL;
}
};