解题思路:明确交换步骤,记录必要的临时节点
ListNode* swapPairs(ListNode* head) {
ListNode* dummy_head = new ListNode(0);
dummy_head->next = head;
ListNode* cur = dummy_head;
while(cur->next && cur->next->next) {
// 临时记录
ListNode* temp1 = cur->next;
ListNode* temp2 = cur->next->next->next;
// 交换步骤
cur->next = cur->next->next;
cur->next->next = temp1;
temp1->next = temp2;
cur = cur->next->next;
}
return dummy_head->next;
}
解题思路:
- 双指针,fast在n的步长基础上再加1,删除slow指向的下一个节点,无需记录pre
- 虚拟头结点,使第一个节点的操作与其他节点相同
ListNode* removeNthFromEnd(ListNode* head, int n) {
// 虚拟头结点用于统一第一个节点与其他节点的操作
ListNode* dummpy_head = new ListNode(0);
dummpy_head->next = head;
// fast先走n步长
ListNode* fast = dummpy_head;
while(n-- > 0) {
fast = fast->next;
if (!fast) {
return head;
}
}
// fast多走一步,这样后续可以直接删除slow指针指向的下一个节点
fast = fast->next;
ListNode* slow = dummpy_head;
while(fast) {
fast = fast->next;
slow = slow->next;
}
// 删除操作
ListNode* temp = slow->next;
slow->next = slow->next->next;
delete temp;
return dummpy_head->next;
}
解题思路:计算两链表长度差值,长链表先走差值,后依次相比
ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
// 计算两链表长度
ListNode* calculate_a = headA;
int len_a = 0;
while(calculate_a) {
len_a++;
calculate_a = calculate_a->next;
}
ListNode* calculate_b = headB;
int len_b = 0;
while(calculate_b) {
len_b++;
calculate_b = calculate_b->next;
}
// 归类长、短链表
ListNode* long_list_head = nullptr;
ListNode* short_list_head = nullptr;
int diff = 0;
if (len_a > len_b) {
long_list_head = headA;
short_list_head = headB;
diff = len_a - len_b;
} else {
long_list_head = headB;
short_list_head = headA;
diff = len_b - len_a;
}
// 长链表先走
while (diff-- > 0) {
long_list_head = long_list_head->next;
}
// 找相交节点
while(long_list_head) {
if (long_list_head == short_list_head) return long_list_head;
long_list_head = long_list_head->next;
short_list_head = short_list_head->next;
}
return NULL;
}
解题思路:
- 判断是否有环可以通过慢指针能否追上快指针判断
- 在头结点与快慢指针相遇的节点出重新出发一个指针,再次相遇时即为环的入口
ListNode *detectCycle(ListNode *head) {
ListNode* fast = head;
ListNode* slow = head;
while(slow && fast && fast->next) {
slow = slow->next;
fast = fast->next->next;
// 如果有环
if (slow == fast) {
ListNode* index1= head;
ListNode* index2= fast;
// 头结点与相遇节点重新出发指针
// 两指针相遇时则为环的入口
while (index1 != index2) {
index1 = index1->next;
index2 = index2->next;
}
return index1;
}
}
return NULL;
}