leetcode24.两两交换链表中的节点

2020-04-13  本文已影响0人  憨憨二师兄

题目链接

解法一:迭代

代码如下:

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */
class Solution {
    public ListNode swapPairs(ListNode head) {
        if(head == null || head.next == null){
            return head;
        }
        ListNode dummyHead = new ListNode(-1);
        dummyHead.next = head;
        ListNode cur = dummyHead;
        while(head != null && head.next != null){
            ListNode next = head.next;
            cur.next = next;
            head.next = next.next;
            next.next = head;
            cur = head;
            head = head.next;
        }
        return dummyHead.next;
    }
}

对于本题,我引入了一个dummyHead,让dummyHead作为head的前驱节点,即:dummyHead.next = head
这样做的原因是:如果从head开始迭代,我们不需要考虑head节点的前驱;但是迭代到链表的中间部分,我们就需要考虑当前遍历的节点和前驱的关系。引入dummyHead 就可以让问题的分析整齐划一。
对于while循环部分,可以参考我的示例图进行理解:
原始链表的状态:

经过如下代码变换后:

cur.next = next;
head.next = next.next;
next.next = head;

链表状态如下:



然后再将cur指向head,head指向head.next即可:

cur = head;
head = head.next;

对于链表的问题,只要涉及到迭代,一定要在纸上写写画画,千万不要像我的某个朋友一样全凭大脑想象,这样的话是无法想到答案的。
执行结果如下:


解法二:递归

代码如下:

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */
class Solution {
    public ListNode swapPairs(ListNode head) {
        if(head == null || head.next == null){
            return head;
        }
        ListNode second = head.next;
        ListNode third = head.next.next;
        second.next = head;
        head.next = swapPairs(third);
        return second;
    }
}

代码执行情况:


递归的思路实际上是以每两个节点作为一个划分单元,首先让second节点的next指向head,这一步是让单元内的节点发生swap;然后让head.next指向下一个单元返回的头结点,即:head.next = swapPairs(third)
相比于迭代方法,递归的写法更容易理解,也更巧妙一些。迭代和递归的时间复杂度均为O(n),虽然递归额外调用了栈,但是我更推荐递归的写法。

上一篇 下一篇

猜你喜欢

热点阅读