24.两两交换链表中的节点
自己想的方法是使用三个指针进行位置修改操作,原理如图所示,我的操作顺序是按照黄色的1,2,3来进行的
class Solution {
public:
ListNode* swapPairs(ListNode* head) {
if(head == NULL || head->next == NULL) return head;
ListNode* dummy = new ListNode(-1);
dummy->next = head;
ListNode* cur = head;
ListNode* pre = dummy;
ListNode* nx = cur->next;
while(cur != NULL){
ListNode* t = nx->next;
cur->next = t;
nx->next = cur;
pre->next = nx;
pre = cur;
cur = t;
if(cur == NULL || cur->next==NULL) break;
nx = cur->next;
}
return dummy->next;
}
};
19.删除链表的倒数第N个结点
定义两个指针cur和pre,先让cur走n步,这个时候cur和pre中间的节点数为n-1,然后让cur和pre同时向后移动,等到cur为最后一个节点的时候,这个时候pre移动到了需要删除节点的前一个节点的位置,之后进行删除操作即可。
class Solution {
public:
ListNode* removeNthFromEnd(ListNode* head, int n) {
ListNode* dummy = new ListNode(-1);
dummy->next = head;
ListNode* pre = dummy;
ListNode* cur = dummy;
while(n--){
cur = cur->next;
}
while(cur->next != NULL){
cur = cur->next;
pre = pre->next;
}
ListNode* p = pre->next;
pre->next = p->next;
delete p;
return dummy->next;
}
};
链表相交
如果存在交点,则交点之后的每个节点都相同,无需继续遍历。
问题是两个链表的指针该如何相遇?
首先需要计算两个链表的长度,让长链表的对应指针先走他们长度的差值,后面两个链表的指针同时走,这样才能相遇
class Solution {
public:
int getLength(ListNode* head){
int len = 0;
ListNode* a = head;
while(a != NULL){
len++;
a = a->next;
}
return len;
}
ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
int lena = getLength(headA);
int lenb = getLength(headB);
ListNode* fast,*slow;
int delta;
if(lena > lenb){
delta = lena - lenb;
fast = headA, slow = headB;
}
else{
delta = lenb - lena;
fast = headB, slow = headA;
}
while(delta--){
fast = fast->next;
}
while(fast != slow && fast != NULL){
fast = fast->next;
slow = slow->next;
}
return fast;
}
};
环形链表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;
// 有环
if(slow == fast){
ListNode* p = fast;
ListNode* q = head;
while(p!=q){
p = p->next;
q = q->next;
}
return p;
}
}
return NULL;
}
};