[路飞]_leetcode 24.两两交换链表中的节点

177 阅读1分钟

题目描述

leetcode 24.两两交换链表中的节点

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

示例

  image.png 示例 1:

输入: head = [1,2,3,4]
输出: [2,1,4,3]

示例 2:

输入: head = []
输出: []

示例 3:

输入: head = [1]
输出: [1]

  提示:

  • 链表中节点的数目在范围 [0, 100] 内
  • 0 <= Node.val <= 100

解题思路

  1. 递归实现
  • 实现两两交换,如果节点数小于两个,直接返回
  • 两个一组,把每组看成一个独立的小链表;
  • 每组的尾节点(head.next),就是是反转后头节点newHead
  • 然后让反转后的尾节点(原头节点),指向后面的反转完的节点;
  • 最后让反转后的新的头节点 指向 原头节点
  1. 迭代实现
  • 创建虚拟头节点ret,虚拟头节点指向原头节点;
  • 找待反转区域的前一节点p,初始定义p = ret;
  • p -> node1 -> node2 -> ....
  • 第一个原链表节点node1, 第二个节点node2, 实现node1与node2反转;
  • ret -> node2;虚拟指向node2
  • node1 -> node2.next
  • node2 -> node1
  • 最后:p -> node2 -> node1 -> ....
  • 第一组反转完成,
  • 第二组要反转,先找待反转前一位,让 p = node1

javascript实现

/**
 * Definition for singly-linked list.
 * function ListNode(val, next) {
 *     this.val = (val===undefined ? 0 : val)
 *     this.next = (next===undefined ? null : next)
 * }
 */
/**
 * @param {ListNode} head
 * @return {ListNode}
 */
var swapPairs = function(head) {
    // 递归实现
    // 实现两两交换,如果节点数小于两个,直接返回
    //if(head == null || head.next == null) return head;
    // 两个一组,把每组看成一个独立的小链表;
    // 每组的尾节点(head.next),就是是反转后头节点newHead
    // 然后让反转后的尾节点(原头节点),指向后面的反转完的节点; 
    // 最后让反转后的新的头节点 指向 原头节点
    // let newHead = head.next;
    // head.next = swapPairs(newHead.next); 
    // newHead.next = head;
    // return newHead

    // 迭代实现
    if(head == null || head.next == null) return head;
    // 创建虚拟头节点ret,虚拟头节点指向原头节点
    let ret = new ListNode(0, head), p = ret;
    while(p.next && p.next.next){
        let node1 = p.next, node2 = p.next.next; // 待反转的两个节点,
        p.next = node2; // 让待反转区域的前一节点,指向待反转区域的最后一个节点
        node1.next = node2.next;// 让node1指向 原node2指向的节点
        node2.next = node1;
        p = node1; // p 为下一组待反转的前一节点
    }
    return ret.next


};

图例分析

image.png

配套视频讲解 www.bilibili.com/video/BV1Ja…