24. 两两交换链表中的节点
① 使用虚拟节点
② 最后返回头结点的时候,head 本来的头节点已经和第二位交换了,需要重新赋值
③ 使用临时指针保存变量
④ 如果是空的不用特殊判断,空的返回头节点也还是空的
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;tmp->next = tmp1;cur = cur->next->next;}head = dummyHead->next;return head;}
};
19. 删除链表的倒数第 N 个结点
① 快慢指针,先让 fast 走 n 步,快指针和慢指针之间相差 n,然后两个指针同时走,fast 走到最后的时候,slow 就是倒数第 n 个
②fast 走了 n 以后,要再向前走一个,因为删除的时候,slow 需要指到删除节点的前一个
③ 使用虚拟头节点会更方便
class Solution {
public:ListNode* removeNthFromEnd(ListNode* head, int n) {//虚拟头节点ListNode* dummy = new ListNode(0);dummy->next = head;ListNode* fast = dummy;ListNode* slow = dummy;//fast先走n步while(n-- && fast != nullptr){fast = fast->next;}//fast多走一步,这样slow就可以指向删除节点的上一个节点fast = fast->next;while(fast != nullptr){fast = fast->next;slow = slow->next;}slow->next = slow->next->next;return dummy->next;}
};
面试题 02.07. 链表相交
① 先计算链表长度然后使两个链表末尾对齐,再让指针走到同一个长度位置,开始逐一对比后边的节点是否是一样的
② 要考虑哪个链表更长的问题
③ 让长的链表的指针走到短的链表头节点位置的时候,走的是链表差值不是链表长度
④ 第一次计算链表长度的时候,最后指针记得要回头节点的位置
/*** 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* cur1 = headA;ListNode* cur2 = headB;int lenA = 0;int lenB = 0;//计算链表长度while(cur1 != nullptr){lenA++;cur1 = cur1->next;}while(cur2 != nullptr){lenB++;cur2 = cur2->next;}cur1 = headA;cur2 = headB;//末尾对其if(lenA>lenB){for(int i=0; i<lenA - lenB;i++){cur1 = cur1->next;}}else{for(int i=0; i<lenB - lenA;i++){cur2 = cur2->next;}}while(cur1 != nullptr && cur2 != nullptr){if(cur1 == cur2){return cur1;}cur1 = cur1->next; // 移动cur1cur2 = cur2->next; // 移动cur2}return NULL;}
};