24.两两交换链表的节点
https://leetcode.cn/problems/swap-nodes-in-pairs/
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;
}
};
先设置虚拟头节点,还要注意设置两个临时的指针,否则cur指向改变后原来的链表就找不到了
1⃣️cur指向第二个节点,原本dummy Head与Head断开
2⃣️新的cur指向Head , 原来tmp1断开
3⃣️让原来的Head指向tmp1的节点
4⃣️cur向前移动两个节点
19.删除链表的倒数第N个节点
lass Solution {
public:
ListNode* removeNthFromEnd(ListNode* head, int n) {
ListNode* dummyHead = new ListNode(0);
dummyHead -> next = head;
ListNode* fast = dummyHead;
ListNode* slow = dummyHead;
while(n-- && fast!=nullptr){
fast = fast -> next;
}
fast = fast ->next;
while(fast != nullptr){
fast = fast -> next;
slow = slow -> next;
}
ListNode *tmp = slow->next;
slow -> next = slow -> next -> next;
slow -> next = tmp -> next;
delete tmp;
return dummyHead -> next;
}
};
利用双指针,快指针先遍历N个节点,然后和慢指针一起遍历到最后,这时候慢指针对应的节点就是倒数第N个节点,但是删除节点需要用的是前一个节点,所以让快指针遍历N+1个节点,慢指针就会少遍历一次,就得到了第N个节点前一个节点。
142.环形链表 II
https://leetcode.cn/problems/linked-list-cycle-ii/
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(fast == slow){
ListNode* index1 = fast;
ListNode* index2 = head;
while(index1 != index2){
index1 = index1 -> next;
index2 = index2 -> next;
}
return index2;
}
}
return NULL;
}
};
采用双指针法,定义快慢指针,快指针每次移动两个节点,慢指针每次移动一个节点,可以看作慢指针不动,快指针每次移动一个节点,也就不存在跳过慢指针的情况。
当快慢指针相等说明有环,定义index1,index2,从头结点出发一个指针,从相遇节点 也出发一个指针,这两个指针每次只走一个节点, 那么当这两个指针相遇的时候就是 环形入口的节点。