while(cur->next != nullptr && cur->next->next != nullptr) 继续进行链表交换的条件是cur指针下一个结点不为空且下下个结点也不为空。如果只剩下一个结点(即链表中是奇数个结点)也没必要交换了。
时间复杂度O(n)
空间复杂度O(1)
/**
* 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 != nullptr && cur->next->next != nullptr){
ListNode* temp=cur->next;
ListNode* temp1=cur->next->next->next;
cout<<"jiaohuan"<<temp->val<<endl;
//cout<<"jiaohuan"<val<
cur->next=cur->next->next;
cur->next->next=temp;
temp->next=temp1;
cout<<"jiaohuan"<<cur->val<<endl;
cout<<"jiaohuan"<<cur->next->val<<endl;
cout<<"jiaohuan"<<cur->next->next->val<<endl;
cur=cur->next->next;
cout<<"jiaohuan"<<cur->val<<endl;
}
return dummyhead->next;
}
};
当下反应的思路是先遍历链表,算链表的长度,再算倒数第N个结点是正数第几个,但这样时间复杂度是o(2n)即遍历了两边。
拓展版用双指针只对链表遍历了一遍,时间复杂度O(N),让快指针先走N步,或者N-1步(根据while判断条件的不同),然后slow指针再一起向前走,这样,随着快指针走到终点,保证慢指针走到删除结点的前一个,即可进行操作了,记得借助temp指针先保存要删除的结点,再进行cur->next=cur->next->next;
空间复杂度都是O(1)
/**
* 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* slow = dummyhead;
ListNode* fast = dummyhead;
while(n-- && fast->next != nullptr){
fast = fast->next;
}
while(fast->next != nullptr){
slow=slow->next;
fast=fast->next;
}
ListNode* temp=slow->next;
slow->next=slow->next->next;
delete temp;
return dummyhead->next;
}
};
/**
* 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) {
ListNode* curA = headA;
ListNode* curB = headB;
int LengthA=0,LengthB=0;
while(curA->next != NULL){
curA=curA->next;
LengthA++;
}
while(curB->next != NULL){
curB=curB->next;
LengthB++;
}
curA=headA;curB=headB;
if(LengthA<LengthB){
swap(LengthA,LengthB);
swap(curA,curB);
}
int gap=LengthA-LengthB;
while(gap--){
curA=curA->next;
}
while(curA != NULL && curB != NULL && curA!=curB){
curA=curA->next;
curB=curB->next;
}
return curA;
}
};
关于什么时候return null还是需要多思考一下详细见代码注释
/**
* 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 ){
slow = slow->next;
fast = fast->next->next;
if(slow == fast){
ListNode* index=head;
ListNode* index1=fast;
while(index != index1){
index=index->next;
index1=index1->next;
}
return index;
}
//else 如果在这里就return null的话相当每一次循环的快慢指针不相等都会return null
//return NULL;
}
return NULL;
}
};