力扣24.两两交换链表中的节点
创建虚拟头节点
class Solution {
public:
ListNode* swapPairs(ListNode* head) {
ListNode* dummyhead = new ListNode(0);
dummyhead->next = head;
ListNode* p = dummyhead;
while(p->next && p->next->next){
ListNode* temp = p->next;
p->next = p->next->next;
temp->next = p->next->next;
p->next->next = temp;
p = p->next->next;
}
return dummyhead->next;
}
};
力扣19. 删除链表的倒数第 N 个结点
创建虚拟头节点
class Solution {
public:
ListNode* removeNthFromEnd(ListNode* head, int n) {
ListNode* dummyhead = new ListNode(0);
dummyhead->next = head;
ListNode* p = dummyhead;
int size = 0;
while(p->next){
size ++;
p = p->next;
}
p = dummyhead;
for(int i = 0; i < size - n; i ++ ){
p = p->next;
}
p->next = p->next->next;
return dummyhead->next;
}
};
力扣面试题 02.07. 链表相交
从前往后看确实是不对齐的,但从后往前看是对齐的!
求和法:
class Solution {
public:
ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
ListNode* pA = headA; //A链表 + B链表
ListNode* pB = headB; //B链表 + A链表
while (pA != pB) { //上述两链表长度相同,找到最开始的交点即可
pA = (pA == nullptr) ? headB : pA->next;
pB = (pB == nullptr) ? headA : pB->next;
}
return pA;
}
};
求差法:
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;
// 让curA为最长链表的头,lenA为其长度
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;
}
};
力扣142. 环形链表 II
不成熟的想法,破坏了链表结构
class Solution {
public:
ListNode *detectCycle(ListNode *head) {
//在链表外创建新节点
ListNode* p = new ListNode(0);
//head == nullptr即为没有环
//head->next == p即为有环且第一个节点为head
while(head && head-> != p){
ListNode* temp = head->next;
if(head->next == p) return head;
head->next = p;
head = temp;
}
return head;
}
};
快慢指针法
class Solution {
public:
ListNode *detectCycle(ListNode *head) {
ListNode* fast = head;
ListNode* slow = head;
while(fast != NULL && fast->next != NULL) {
//两者速度之差为1,所以说在环内fast是以相对于slow为1的速度追赶
//所以如果有环的话两者一定能在环内相遇
slow = slow->next;
fast = fast->next->next;
// 快慢指针相遇,此时从head 和 相遇点,同时查找直至相遇
//把链表分为三部分:x(成环前) + y(环的第一个点至两者相遇点)+ z(两者相遇点到环的第一个节点)
//则有 x + y == 2 * (x + n * (y + z))
//化简得 x == (n - 1)(y + z) + z
//所以让两个指针分别从head和相遇点出发,一定会在环的第一个节点相遇
if (slow == fast) {
ListNode* index1 = fast;
ListNode* index2 = head;
while (index1 != index2) {
index1 = index1->next;
index2 = index2->next;
}
return index2; // 返回环的入口
}
}
return NULL;
}
};