24. 两两交换链表中的节点
厘清楚指针处理的先后顺序再进行操作,不然容易乱。然后每次cur移动移两个。
/**
* 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(0);
dummyhead->next = head;
ListNode* cur = dummyhead;
while(cur->next!=NULL && cur->next->next!=NULL){
ListNode * temp1 = cur->next;
ListNode * temp2 = cur->next->next->next;
cur->next = cur->next->next;
cur->next->next = temp1;
cur->next->next->next = temp2;
cur = cur->next->next;
}
return dummyhead->next;
}
};
19.删除链表的倒数第N个节点
方法1 思路:首先遍历链表计算出链表长度,然后减去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(0);
dummyhead->next = head;
ListNode* cur = dummyhead;
int count = 0;
while(cur->next != NULL){
cur = cur->next;
count++;
}
cur = dummyhead;
for(int i=0; i<(count-n); i++){
cur = cur->next;
}
ListNode* temp = cur->next;
cur->next = cur->next->next;
delete temp;
return dummyhead->next;
}
};
方法2:双指针
先将r移动n+1步,然后同时移动两个指针,l指针所在的节点是目标节点的上一个节点。
/**
* 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(0);
dummyhead->next = head;
ListNode * l = dummyhead;
ListNode * r = dummyhead;
while(n--&&r->next!=NULL){
r = r->next;
}
r = r->next; //走一步使l落在删除节点的前一位
while(r){
r = r->next;
l = l->next;
}
ListNode* tmp = l->next;
l->next = l->next->next;
delete tmp;
head = dummyhead->next;
delete dummyhead;
return head;
}
};
面试题 02.07. 链表相交
先计算两条链表的长度,并找到长链表,用长的减去短的得到移动的步数,让长链表指针移动该步数。之后同时移动,比较两个指针是否相同,相同就返回该节点。
/**
* 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 len_a = 0,len_b = 0;
ListNode* cura = headA;
ListNode* curb = headB;
while(cura!=NULL){
cura = cura->next;
len_a++;
}
while(curb!=NULL){
curb = curb->next;
len_b++;
}
cura = headA;
curb = headB;
int move;
if(len_a>len_b){
move = len_a-len_b;
while(move--){
cura = cura->next;
}
}
else {
move = len_b-len_a;
while(move--){
curb = curb->next;
}
}
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) {
// 1.判断是否有环
// 2.判断环的结点
//假设从头结点到环形入口节点 的节点数为x。
// 环形入口节点到 fast指针与slow指针相遇节点 节点数为y。
// 从相遇节点 再到环形入口节点节点数为 z。
ListNode* fast = head;
ListNode* slow = head;
while(fast&&fast->next){
fast = fast->next->next;
slow = slow->next;
if(fast==slow){
// 快慢指针相遇,此时从head 和 相遇点,同时查找直至相遇
ListNode* index1 = fast;
ListNode* index2 = head;
while(index1!=index2){
index1 = index1->next;
index2 = index2->next;
}
return index2;
}
}
return NULL;
}
};