js刷leetcode 第24题 交换相邻链表

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

用图表示的话,类似这样 题目示例

首先我们来看循环迭代的解决方法

  1. 我们生成一个辅助节点叫dummy node链接在头节点之前,为什么要链接在头节点之前呢?为了不影响后面头节点与相邻节点交换,更用于方便最后输出整个交换过的链表,如下图

dummy node

  1. 随后我们还需要定义3个变量,prev代表前置节点,n1代表当前节点,n2代表与n1相邻的节点

n1 and n2 and prev node

  1. 申请完变量后,首先将前置节点指向n2,因为交换完成后n2将是第一个节点
prev.next = n2
复制代码

prev link to n2

  1. n1节点指向n2的后一个节点,第一次情况下也就是[3,4]
n1.next = n2.next
复制代码

change n1 link to n2 next

  1. 然后第一次交换相邻节点,将n2节点指向n1节点
n2.next = n1
复制代码

change n2 link to n1

  1. 第一次交换完成后,链表结构变成[-1, 2, 1, 3, 4]这样

after first time iteration

  1. 在迭代的最后,将前置节点prev改变为n1,并将当前节点head改变为n1.next,为第二次迭代做准备
prev = n1;
head = n1.next;
复制代码

set prev and head

  1. 在我们进入下一次迭代前,我们设置迭代条件为有当前节点和当前的下一个节点时才进行交换,这也是符合题目要求的

  2. 最后我们输出辅助节点dummy.next作为交换完的节点,这是因为prev节点在迭代过程中已经被移动了

完整代码如下

var swapPairs = function(head) {
    // build a dummy nodes link to head, like [-1,1,2,3,4]
    let dummy = new ListNode(-1)
    dummy.next = head
    // assign dummy to prev because prev will change to  forward nodes, but dummy always link to first node, in this example is link to [2...]
    let prev = dummy
    
    // loop when head and head.next is not null
    while(head && head.next) {
        // cur node
        let n1 = head
        // next node
        let n2 = head.next
        
        
        // link to next node, first time is [2...]
        prev.next = n2 
        // swap
        n1.next = n2.next
        n2.next = n1

        
        
        // make prev move to forward node for next loop use, for example, first time prev assign to n1, when next loop prev.next like n1.next [1,3,4]
        prev = n1 
        // change head is n1.next
        head = n1.next


    }

    return dummy.next
    
    
    
    

};
复制代码

时间复杂度为O(N),空间复杂度为O(1)

然后我们再来用递归实现一下

  1. 首先设置递归终止条件,当没有当前节点或没有下一个节点时,递归结束
if(!head || !head.next) return head
复制代码
  1. 然后,我们申请3个变量,v1为当前节点,v2为下一个节点,v3为第三个节点
let v1 = head ;
let v2 = v1.next; 
let v3 = v2.next;
复制代码

set three variables

  1. 我们交换v1v2,继续递归v3并赋给v1

swap v1 and v2 and assign recursion v3 to v1

  1. 在函数的最后,我们返回v2, 因为无论是那次递归,v2都将代表本次交换中的第一个节点

完整代码

var swapPairs = function(head){
    // stop
    if(!head || !head.next) return head 
    
        // do
    let v1 = head
    let v2 = v1.next
    let v3 = v2.next
    v2.next = v1

    
    // recursion
    v1.next = swapPairs(v3)
    
    return v2
}
复制代码

参考

LeetCode 24 Swap nodes in pairs

おすすめ

転載: juejin.im/post/7074885077011791909