leetcode-两两交换链表中的节点

486 阅读3分钟

这是我参与8月更文挑战的第15天,活动详情查看:8月更文挑战

昨天看了一下雷军8月10日的演讲视频,想起来去年有一场叫做“一往无前”的演讲,记忆犹新,转眼就要1年了。印象中除了这2次,雷军也很少有其他演讲,比较低调,可能随着市场环境的变化,创始人多出来露面,有助于产品宣传吧。我不是特别的米粉,不过也买过几个小米手机。在我看来,小米最大的优点是,通过强大的供应链管理能力,把原来价格高不可攀的产品,打到了一个普通人很容易接受的程度。小米创业过程中,“专注极致口碑快”这互联网七字诀,也影响了国内一大批互联网行业的创业公司甚至是大企业。

雷军从一个工程师起步,做到今天的成就,挺了不起的。小米手机成了出货量全球第二,另外,小米汽车也让人期待。技术上的精益求精、商业上的敏锐嗅觉、开创新事业的一往无前,都是这个结果缺一不可的因。作为一个技术人,每天让自己技术精进一点,也是一种自我修养吧。

今天做的是leetcode的第24题,还是一题偏向数据结构而不是算法的题目。

题目

给定一个链表,两两交换其中相邻的节点,并返回交换后的链表。
你不能只是单纯的改变节点内部的值,而是需要实际的进行节点交换。
  swap_ex1.jpg 示例 1:
输入:head = [1,2,3,4]
输出:[2,1,4,3]

示例 2:
输入:head = []
输出:[]

示例 3:
输入:head = [1]
输出:[1]

思路

因为要两两交换,所以要判断剩余是否足够2个,只剩下1个的话就不用交换了。
以比较简单的1-2-3这样的一个链表来说明: 先定于一个哑结点dummy,一个指向结果链表的尾节点tail,一个当前处理的指针index,index的后趋指向head。
题解1.png 先判断index是否存在2级后趋,此时index的1级后趋是1,2级后趋是2,存在2个节点就需要交换,交换的步骤是:

  1. index的后趋指向2的后趋3;
  2. tail的后趋指向2;
  3. 2的后趋指向1;
  4. 1的后趋指向空;
  5. 更新tail为节点1; 完成后,就变成了入下图所示: 题解2.png

这时候,index的只有1级后趋了,只要把这个节点跟在tail的后面即可。

Java版本代码

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode() {}
 *     ListNode(int val) { this.val = val; }
 *     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
 * }
 */
class Solution {
    public ListNode swapPairs(ListNode head) {
        ListNode dummy = new ListNode();
        ListNode tail = dummy;
        ListNode index = new ListNode(0, head);
        while (index.next != null) {
            if (index.next.next == null) {
                // 之后1级next,不需要再交换了
                tail.next = index.next;
                index = index.next;
            } else {
                // 存在2级next,需要交换后续的2个节点
                ListNode nextOne = index.next;
                ListNode nextTwo = nextOne.next;
                // index的后趋指向2级next的后趋
                index.next = nextTwo.next;
                // 当前结尾next指向2级next
                tail.next = nextTwo;
                // 2级next的后趋指向1级next
                nextTwo.next = nextOne;
                // 1级next的后趋指向空
                nextOne.next = null;
                // 更新tail
                tail = nextOne;
            }
        }
        return dummy.next;
    }
}