day4
19.删除链表的倒数第N个节点
160.链表相交,第一眼自己都没想出解法
24. 两两交换链表中的节点
只要指针设得够多,就能做出来/doge
虚拟结点用的比较习惯了。
发现链表里的题,用指针的话,往往要三个。
class Solution {
public:
ListNode* swapPairs(ListNode* head) {
// if (!head || !head->next) return head;
ListNode* dummy = new ListNode(0, head);
ListNode* pre = dummy;
while (pre->next && pre->next->next) {
ListNode* tmp = pre->next;
pre->next = tmp->next;
ListNode* tmp2 = pre->next->next;
pre->next->next = tmp;
tmp->next = tmp2;
pre = tmp;
}
return dummy->next;
}
};
19.删除链表的倒数第N个节点
先走n步的双指针一次循环到位,确实没想到,但是这样真的算是一次遍历吗?
两个指针走的次数,和一个指针走两次的次数,理论上是一样的。
class Solution {
public:
ListNode* removeNthFromEnd(ListNode* head, int n) {
ListNode* dummy = new ListNode(0, head);
ListNode *fast = dummy, *slow = dummy;
while (fast && n--) {
fast = fast->next;
}
if (!fast) return dummy->next;
while (fast->next) {
fast = fast->next;
slow = slow->next;
}
ListNode *tmp = slow->next;
slow->next = tmp->next;
delete tmp;
return dummy->next;
}
};
面试题 02.07. 链表相交( 160.链表相交 )
从计算机的角度来看,链表相交的等价条件:指针一样。
题目突破口肯定是相交之后的部分,先把两个指针调整到离终点距离相同的程度,问题就迎刃而解。
class Solution {
public:
int getLength(ListNode* head) {
int length = 0;
ListNode* p = head;
while (p) {
length++;
p = p->next;
}
return length;
}
ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
int lenA = getLength(headA), lenB = getLength(headB);
int diff = lenA - lenB;
ListNode* p = diff > 0 ? headA : headB;
ListNode* q = diff > 0 ? headB : headA;
diff = diff > 0 ? diff : -diff;
while (diff) {
p = p->next;
diff--;
}
while (p) {
if (p == q) {
return p;
}
p = p->next;
q = q->next;
}
return NULL;
}
};
142.环形链表II
这题想不出来,我记得是和快慢指针相关,fast步速是slow两倍。
这道题的理论证明看了一遍,要证明可以排除的情况有点复杂。如果面试碰到,我选择放弃证明,直接背代码。
- fast走两步,slow走一步,找到相遇的地方;
- 两个指针从fast和head处分别开始走,相遇的地方就是入口。
class Solution {
public:
ListNode *detectCycle(ListNode *head) {
ListNode* fast = head, *slow = head;
while (fast && fast->next) {
fast = fast->next->next;
slow = slow->next;
if (fast == slow) {
ListNode* p1 = head;
ListNode* p2 = fast;
while (p1 != p2) {
p1 = p1->next;
p2 = p2->next;
}
return p1;
}
}
return nullptr;
}
};
总结
day4的后三个题都用到了快慢指针,或者保持一定差值,或者移动速度不同。