[24] Swap Nodes in Pairs

1. 题目描述

Given a linked list, swap every two adjacent nodes and return its head.

For example,
Given 1->2->3->4, you should return the list as 2->1->4->3.

Your algorithm should use only constant space. You may not modify the values in the list, only nodes itself can be changed.

交换一个单项链表中相邻的元素,且不使用多余的空间,只操作单向链表中的节点指针。

2. 解题思路

一般链表操作我首先先考虑链表为空和只有一个节点的情况,一般这种情况都直接返回,这个题也如是,一个节点不用交换了,直接返回head就好。之后就要开始仔细考虑在操作链表指针的过程中,断开一个指针的时候有没有其他指针指向他后面的元素,如果没有很有可能会发生丢失,还有就是如果我想操作这个节点的前一个或前几个节点的时候,必须也要存下来,因为他是一个单向链表,过去了就找不回来啦。下面我们再画一个图,来看看这个题应该如何对指针进行操作。
这里写图片描述
既然是要进行交换操作,那么至少就需要两个指针p, q。所谓交换两个节点,就是原本q的next要指向p,原本p的next要指向q的next,这就完成了两个节点的交换。过程如图12,3为完成一次交换后的结果。之后我们将p、q后移对下一组进行操作,这时就发现了一个问题,如果3、4进行交换了,1还是指向3的,这样4就丢了,所以1应该修改next指向4才对。这种问题发生在后面有偶数个元素的情况,即如果后面没有4,到3就结束了,那么1指向3是对的。所以就发现了跟之前重合的部分,因为q如果为空的时候即最后只有一个节点了,压根就不用交换了,也就直接结束了操作。所以当q不为空时,我们需要修改1的next指针,指向交换后在前面的元素。所以我们定义一个r,保存住原来1的位置,进入下一轮操作时,将r的next修改为q,其他的过程还保持不变。宗旨看图应该就可以看明白啦XD

3. Code

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */
public class Solution {
    public ListNode swapPairs(ListNode head) {
        // 链表只有一个节点或没有节点直接返回
        if (head == null || head.next == null)
        {
            return head;
        }
        // 创建两个暂存指针,指向head和head的下一个元素
        ListNode p = head;
        ListNode q = head.next;
        // 因为交换改变了head,所以head需要移动到下一个元素
        head = head.next;
        ListNode r = null;
        // q等于空时,只有一个元素,不用进行交换
        while(q != null)
        {
            if(r != null)
            {
                r.next = q;  // ③
            }
            p.next = q.next;  // ①
            q.next = p;  // ②
            r = p;
            p = p.next;  // p向后移动到p’
            // 当p为空时,后面就没有节点了,证明操作已经完成
            if(p == null) break;
            q = p.next;  // q向后移动到q’
        }
        return head;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值