只要涉及到链表结点的
删除或交换
,就必须
新建虚拟头结点
newHead->next=head,让f指针指向newHead作为前置结点指针(删除和交换都需要前置结点指针的),newHead当然不动,程序最后返回的是newHead->next。
两个两个地交换结点
两个两个地就地交换结点。
大致思路:
一定要
先新建一个虚拟结点newHead
,newHead->next=head,这样的话就算head被交换,最终返回的是newHead->next,也是正确的结果链表头结点。
交换的方法一定要注重逻辑,如图:1和2交换,先令1->next=3,然后再让2->next=1,并且让上一节点f->next=2.这之后呢,变化p和f指针的位置,继续下一次的两两交换。
AC代码:
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode *swapPairs(ListNode *head) {
if(head==NULL)
return head;
if(head->next==NULL)
return head;
ListNode *f = new ListNode(0);
ListNode *real_head = f;
f->next = head;
ListNode *p = head;
while(p!=NULL && p->next!=NULL)
{
ListNode *q = p->next;
p->next = q->next;
q->next = p;
f->next = q;
f = p;
p = p->next;
}
return real_head->next;
}
};
K个K个地交换
这次是每轮要有K个交换,如果最后一轮不足K个则不动。
大致思路:
设置虚拟头结点newHead是肯定需要的!
不同点在于,需要先去找到后面的第k-1个,先把下一轮的头找到(比如这里的4),1->next=4之后,再进行k-1次的头插,这之后,让f=1,p=4,开始下一轮。
我觉得我编程中出现了比较傻的问题就是把while写成if了。。。还看半天看不出来。。。这要不得哈。。。然后,一定要注意这种承接关系(比如4和1)在交换之前先保存好。
AC代码:
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
int k;
ListNode *reverseKGroup(ListNode *head, int kk) {
k=kk;
if(k==0 || k==1)
return head;
if(head==NULL)
return head;
if(head->next==NULL)
return head;
ListNode *f = new ListNode(0);
ListNode *real_head = f;
f->next = head;
ListNode *p = head;
while(p!=NULL)
{
int cnt=0;
ListNode *q = p;
while(q->next!=NULL)
{
cnt++;
q=q->next;
if(cnt==k-1)
break;
}
if(cnt<k-1)
break;
ListNode *next_head = q->next;
q = p->next;
p->next=next_head;
ListNode *this_tail = p;
for(int i=0;i<k-1;i++)
{
ListNode *a = q;
q = q->next;
a->next=p;
p = a;
f->next = a;
}
p = next_head;
f = this_tail;
}
return real_head->next;
}
};
版权声明:本文为m0_38033475原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。