两两交换链表中的结点

一、题目介绍

题目链接(力扣上第24题)

给你一个链表,两两交换其中相邻的节点,并返回交换后链表的头节点。你必须在不修改节点内部的值的情况下完成本题(即,只能进行节点交换)。

示例:

二、两种方法

迭代法:

ListNode* swapPairs(ListNode* head) {
        if(head==NULL||head->next==NULL)
        return head;
        ListNode* dummy=new ListNode(0,head);
        ListNode* pre=dummy;
        ListNode* cur=head;
        while(cur&&cur->next)
        {
            ListNode* next=cur->next;
            pre->next=next;
            cur->next=next->next;
            next->next=cur;
            pre=cur;
            cur=cur->next;
        }
        head=dummy->next;
        delete dummy;
        return head;
    }

 思路:

1.先从结点数少时想起:当没有结点或者只有一个结点时,直接返回head就可以了.

2.当有两个或者三个结点时(可以代表一般情况):

定义三个指针:

cur:需要交换的两个结点中的前一个结点;

next:cur的下一个结点,即两个结点中的后一个结点;

pre:cur的前一个结点,用来连接需要交换的两个结点:

主要算法步骤:

1.pre->next=next;  cur->next=next->next;  next->next=cur;  结点交换连接过程;

2.pre=cur;  cur=cur->next;  遍历过程;

3.while(cur&&cur->next)      循环判断条件,当当前遍历.的需要交换的一组结点中的第一个结点或者第二个结点为空时,结束循环;(其实一开始对head的判断可以省略,这里也可以判断);

细节:

1.由于有pre->next=next操作,但是当交换第一组结点时,前面没有结点,故需要定义一个哨兵位结点dummy,并给pre赋值为dummy;

2.next在循环里定义就好了,直接next=cur->next即可,不用在while循环开始前就定义;

递归法:

 ListNode* swapPairs(ListNode* head) {
       if(head==NULL||head->next==NULL)
       return head;
       ListNode* second=head->next;
       head->next=swapPairs(second->next);
       second->next=head;
       return second;
    }

思路:

递归三部曲:
1.确定函数返回值和函数参数:每次返回交换后的一组结点中的前一个结点,使交换后的一组结点能够与其前面的结点连接;每次传递的参数为需要交换的一组结点中的前一个结点;

2.判断终止条件:很显然,当每一组需交换结点组中的head或者head->next为NULL时,终止;

3.单层递归逻辑:每次传参为需交换结点组中的前一个结点,以第一次归的过程思考,函数的返回值要么为空,要么为最后一个结点(链表中结点个数为奇数),再想想交换过程,即head->next=返回值,second->next=head;此时second为结点组中的第一个结点,再返回second,让上一个结点组进行相同操作,最终返回的second即为整个交换后链表的头结点; 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值