24. 两两交换链表中的节点
需要两个临时变量存储下一次要交换的节点地址
class Solution {
public:
ListNode* swapPairs(ListNode* head) {
ListNode* pre=head;
//长度为0或者1直接返回
if(head==NULL){
return head;
}
ListNode* current=head->next;
if(current==NULL){
return head;
}
ListNode*temp1=NULL;
ListNode*temp2=NULL;
struct ListNode* dummyHead=(struct ListNode*)malloc(sizeof(struct ListNode));
dummyHead->next=head;
current=dummyHead;
while(current->next!=NULL&¤t->next->next!=NULL){
temp1=current->next->next->next;
current->next->next->next=current->next;
temp2=current->next;
current->next=current->next->next;
temp2->next=temp1;
//直接后移两个结点
current=current->next->next;
}
return dummyHead->next;
}
};
19.删除链表的倒数第N个节点
不用先计算链表长度,用虚拟头节点,先让快的指针多走n下,他走完了自然就找到了要删的节点的上一个节点
class Solution {
public:
ListNode* removeNthFromEnd(ListNode* head, int n) {
struct ListNode* dummyHead=(struct ListNode*)malloc(sizeof(struct ListNode));
dummyHead->next=head;
//设置快慢指针
struct ListNode* fast=dummyHead;
struct ListNode* slow=dummyHead;
for(int i=0;i<n+1;i++){
fast=fast->next;
}
//有可能此时已经走到了NULL
if(fast==NULL){
struct ListNode* temp=slow->next;
slow->next=slow->next->next;
delete temp;
return dummyHead->next;
}
//快指针开局没有走到NULL
//快指针先走n+1步,这样等快慢指针同时移动的时候,快指针指向NULL时慢指针就指向被删除结点的前驱结点了
while(fast){
fast=fast->next;
slow=slow->next;
}
//fast指向了null
struct ListNode* temp=slow->next;
slow->next=slow->next->next;
delete temp;
return dummyHead->next;
}
};
面试题 02.07. 链表相交
这题还可以用set做
ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
//双指针法
//类似于那个环形链表的做法
//1.假设相交,相交之后的长度为C,相交之前分别走了A和B
//根据等式A+B=B+A 如果最后相等于某一个结点,则返回该结点
//2.如果两个不相交,A和B就变成了各自的长度,不再是相交之前的长度了
ListNode* p1=headA;
ListNode* p2=headB;
while(p1!=p2){
if(p1!=NULL){
p1=p1->next;
}else{
p1=headB;
}
if(p2!=NULL){
p2=p2->next;
}else{
p2=headA;
}
}
return p1;
}
142.环形链表II
class Solution {
public:
ListNode *detectCycle(ListNode *head) {
//首先判断链表是否有环
//用快慢指针是否相遇来判断是否有环
struct ListNode* fast=head;
struct ListNode* slow=head;
//用fast来做循环条件,因为fast走得快,如果它走到头说明一定没有环,fast能走说明slow就不需要判断下一步是否为空了
while(fast&&fast->next&&fast->next->next){
fast=fast->next->next;
slow=slow->next;
if(fast==slow){
//相遇说明有环
struct ListNode* index1=head;
struct ListNode* index2=slow;
while(index1!=index2)
{
index1=index1->next;
index2=index2->next;
}
//因为fast一次走两步,所以在环内slow走一步的条件下,slow再走一环的时间内,fast一定可以追上slow
return index1;
}
}
return NULL;
}
};