24. 两两交换链表中的节点
思路:要用虚拟头结点,不然如果数组为空或者只有一个的情况需要单独讨论。在循环中需用两个节点,一个是指向需交换的第一个节点位置。因为需要先将前一个结点的地址指向需交换的结点,然后做交换。第二个是需交换第二个结点的下一个结点位置。
/** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * ListNode() : val(0), next(nullptr) {} * ListNode(int x) : val(x), next(nullptr) {} * ListNode(int x, ListNode *next) : val(x), next(next) {} * }; */ class Solution { public: ListNode* swapPairs(ListNode* head) { ListNode* dummyHead = new ListNode(); dummyHead-> next = head; ListNode* cur = dummyHead; while(cur->next!=NULL&&cur->next->next!=NULL){ ListNode* temp1 = cur->next->next->next; ListNode* temp2 = cur->next; cur->next = cur->next->next; cur->next->next =temp2; temp2->next = temp1; cur = cur->next->next; } return dummyHead->next; } };
19.删除链表的倒数第N个节点
思路:运用双指针的方法,需要删除某个结点就必须让满指针指向需删除结点的前一个。
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode() : val(0), next(nullptr) {}
* ListNode(int x) : val(x), next(nullptr) {}
* ListNode(int x, ListNode *next) : val(x), next(next) {}
* };
*/
class Solution {
public:
ListNode* removeNthFromEnd(ListNode* head, int n) {
ListNode* dummyHead = new ListNode();
dummyHead->next = head;
ListNode* slowIndex = dummyHead;
ListNode* fastIndex = dummyHead;
while(n--){
fastIndex = fastIndex->next;
}
while(fastIndex->next!=NULL){
slowIndex = slowIndex->next;
fastIndex = fastIndex->next;
}
if(fastIndex->next == NULL){
ListNode* p =slowIndex->next;
slowIndex->next = slowIndex->next->next;
delete p ;
}
return dummyHead->next;
}
};
07. 链表相交
思路:将长度长的链表统一放在下面,利用长度差将两个链表的指针放在同一索引下一起移动。当两个指针相等时则现相交否则返回NULL;
/** * 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) { int lenA = 0; int lenB = 0; ListNode* curA = headA; ListNode* curB = headB; while(curA){ lenA++; curA = curA->next; } curA = headA; while(curB){ lenB++; curB = curB->next; } curB = headB; if(lenA>lenB){ swap(lenA,lenB); swap(curA,curB); } int gap = lenB -lenA; while(gap--){ curB = curB->next; } while(curA){ if(curA==curB){ return curB; } curA = curA->next; curB = curB->next; } return NULL; } };
142.环形链表II
思路:快慢指针会在环中相遇,我们把相遇分为三个阶段,第一个阶段为环前为x,第二各阶段在环中相遇为y,剩下的为z。则slow指针会走x+y,它必须在第一个指针相遇。fast 走过。
2x+2y = x+y + n(y+z);化简得 x = (n-1)(y+z) +z;此时我们则再令index1从头结点开始走,index2从相遇地点开始走。当他们相等时则是环开始的结点。
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode *detectCycle(ListNode *head) {
ListNode* slow = head;
ListNode* fast = head;
while(fast!=NULL&&fast->next!=NULL){
fast = fast->next->next;
slow = slow->next;
if(slow == fast){
ListNode* index1 = head;
ListNode* index2 = fast;
while(index1 !=index2){
index1 = index1->next;
index2 = index2->next;
}
return index2;
}
}
return NULL;
}
};