Swap Nodes in Pairs

本文详细解析了链表中双节点交换的三种实现方法:迭代、递归及改进的迭代方式。通过对比不同实现,深入理解算法核心,提供Python工程师面试及工作中的实用技巧。
class Solution {
        public ListNode swapPairs(ListNode head) {
            //定义一个虚拟结点
            ListNode dummy = new ListNode(-1);
            //定义一个前结点指针  pre
            ListNode pre = null;
            //定义一个当前结点指针 cur
            ListNode cur = null;

            //初始化位置
            //让虚拟结点和head结点链接,最后直接返回虚拟结点的下一个结点即是头结点
            dummy.next = head;
            //pre的初始位置,是当前虚拟结点,
            // 即当前结点的前面的结点,
            // 即操作的两个结点的前面的一个结点,来维护操作的两个结点和前面结点的关系的
            pre = dummy;
            //当前结点,指向当前操作的两个结点中的第一个结点,初始化是dummy.next,即head头结点
            // 也可以写为cur = head;
            cur = dummy.next;

            //这里是核心操作!!!
            // 判断条件是结点非空,当前结点的后的一个结点非空,
            // 即保证操作的元素必须是两个结点的单位,1-2  3-4
            // 如果是只有一个结点,则不操作,
            // 如果是空结点也不操作
            while(cur != null && cur.next != null){
                //声明一个last结点指针,主要是操作两个两个结点的后一个结点,
                // last的初始位置是cur的下一个结点
                ListNode last = cur.next;
                //当前结点的next指针指向last的下一个元素,即cur结点的下一个结点的指针变化为第三个元素
                //假设初始结点是0- 1 - 2 - 3 - 4  ,现在是 0-1-3-4  2
                // 2结点的位置保存在last中
                cur.next = last.next;
                //last结点的next指针变成了当前结点 ,现在是 2-1
                //还有上一个步骤结果 0-1-3-4
                //   0-1-3-4
                //     \
                //      2
                last.next = cur;
                //现在就是要链接两个片段
                //pre结点的next指向了last结点,即虚拟结点指向了2结点   0-2-1   即0-2-1-3-4
                //这样就完成了1 2 结点的位置互换
                //     1-3-4
                //     \
                //      2
                //       \
                //        0
                pre.next = last;

                //接下来就是移动元素,开始操作3 、4元素
                //pre指向当前结点,cur=1
                //注意这里不是往后移了一位而是两位,  pre指向了0-2-1-3-4 中的1
                pre = cur;
                //cur指针后移一位,就是3。这样就开始了以3-4为操作单元的的操作单元
                cur = cur.next;
            }

            return dummy.next;
        }
      }
  对比一个不太好的实现
 public ListNode swapPairs(ListNode head) {
        //前节点,为了让整个连接不要断掉
        ListNode pre= new ListNode(0) ;
        //当前需要交换的第一个节点
        ListNode cur = new ListNode(0) ;
        //前一个节点,要保持在cur前面,一遍两两交换的时候能够保持中间连接
        pre.next=cur;
        //第一个要交换的节点
        cur=head;
        //判断边界
        if (head == null || head.next == null) {
            return head;
        }

        while (cur != null && cur.next!= null) {
            //第二个需要交换的节点
            ListNode last =cur.next;
           //交换1,2的节点
           cur.next =last.next;
            last.next = cur;
            //保持基数位置的链接关系
             pre.next=last;
            //由于节点有位置移动,要扶正head的位置
            if(cur==head){
                head = last;
            }
            //前移一位
            pre =cur;
            //在交换过程中有移动了一个步骤,所以这块只移动一个位置
            cur=cur.next;
        }
        return head;
    }

递归

class Solution {
    public ListNode swapPairs(ListNode head) {
      	//终止条件:链表只剩一个节点或者没节点了,没得交换了。返回的是已经处理好的链表
        if(head == null || head.next == null){
            return head;
        }
      	//一共三个节点:head, next, swapPairs(next.next)
      	//下面的任务便是交换这3个节点中的前两个节点
        ListNode next = head.next;
        head.next = swapPairs(next.next);
        next.next = head;
      	//根据第二步:返回给上一级的是当前已经完成交换后,即处理好了的链表部分
        return next;
    }
}

转载于:https://my.oschina.net/zjItLife/blog/3039402

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值