24两两交换链表中的节点
注意使用虚拟头节点,操作接待你在前一位
注意保存指针
class Solution {
public:
ListNode* swapPairs(ListNode* head) {
ListNode* Head=new ListNode(0);
Head->next=head;
ListNode* cur=Head;
while(cur->next!=nullptr&&cur->next->next!=nullptr)//注意顺续,cur->next==nullptr时cur->next->next越界违法
{
ListNode* temp1=cur->next;
ListNode* temp2=cur->next->next;
cur->next=temp2;
temp1->next=temp2->next;
temp2->next=temp1;
cur=cur->next->next;
}
return Head->next;
}
};
19.删除链表的倒数第N个节点
虚拟头节点
双指针,先走n+1(操作节点)
class Solution {
public:
ListNode* removeNthFromEnd(ListNode* head, int n) {
ListNode *Head=new ListNode(0);
Head->next=head;
ListNode* temp1=Head;
ListNode* temp2=Head;
while(n--&&temp1!=nullptr)
{
temp1=temp1->next;
}
temp1=temp1->next;
while(temp1!=nullptr){
temp1=temp1->next;
temp2=temp2->next;
}
temp2->next=temp2->next->next;
return Head->next;
}
};
面试题 02.07. 链表相交
数值相同不一定指针相同
双指针,先让剩余长度相等,狨猴同时向后走比较
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;
}
};
双指针从两头遍历,到头跳到另一个链表继续,若有交集则遍历一次必然相遇在交点位置,若没有则不相交
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;
}
};
hash
/**
* 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) {
unordered_set<ListNode *> visited;
ListNode *temp = headA;
while (temp != nullptr) {
visited.insert(temp);
temp = temp->next;
}
temp = headB;
while (temp != nullptr) {
if (visited.count(temp)) {
return temp;
}
temp = temp->next;
}
return nullptr;
}
};
142.环形链表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;
// 快慢指针相遇,此时从head 和 相遇点,同时查找直至相遇
if (slow == fast) {//x=z
ListNode* index1 = fast;
ListNode* index2 = head;
while (index1 != index2) {
index1 = index1->next;
index2 = index2->next;
}
return index2; // 返回环的入口
}
}
return NULL;
}
};