21. 合并两个有序链表简单链表双指针

Posted pre_eminent

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了21. 合并两个有序链表简单链表双指针相关的知识,希望对你有一定的参考价值。

题目

将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。 

示例 1:


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



示例 2:

输入:l1 = [], l2 = []
输出:[]



示例 3:

输入:l1 = [], l2 = [0]
输出:[0]
 


提示:

两个链表的节点数目范围是 [0, 50]
-100 <= Node.val <= 100
l1 和 l2 均按 非递减顺序 排列


示例图片


思路:

思路1. 转数组→排序→再转链表

思路2. 双指针


解法1:

1. 链表转数组

2. 对数组进行排序(注意:js中sort方法,负数时会出错,因为是按编码顺序排的)

3. 排序后的数组 转链表

/**
 * Definition for singly-linked list.
 * function ListNode(val, next) 
 *     this.val = (val===undefined ? 0 : val)
 *     this.next = (next===undefined ? null : next)
 * 
 */

// List转数组 
var listToArr = function(list) 
    const arr = [];
    // 注意括号中的判断条件
    while(list !== null) 
        arr.push(list.val);
        list = list.next;
    
    return arr;
 

// 数组 转List
var arrToList = function(arr) 
    var head = new ListNode();
    var headCopy = null;
    arr.forEach(i => 
        var node = new ListNode();
        node.val = i;
        node.next = null;
        head.next = node;
        // 重要:动态更新head节点
        head = node;
        // 记住头节点,最后返回值时要用到
        if (headCopy === null) 
            headCopy = node;
        
    )
    return headCopy;


/**
 * @param ListNode list1
 * @param ListNode list2
 * @return ListNode
 */
var mergeTwoLists = function(list1, list2) 
    // 1. list 转数组
    const arr1 = listToArr(list1);
    const arr2 = listToArr(list2);

    // 2. 对数组进行排序
    // 如果调用sort方法时没有使用参数,将按字母顺序对数组中的元素进行排序,
    // 说得更精确点,是按照字符编码的顺序进行排序。
    // 所以负数排序出错
    const arr = [...arr1, ...arr2].sort((a, b) => a - b);

    // 3. 数组 转list
    const list = arrToList(arr);
    return list;
;


解法2:双指针

关键点:(画图 + 过程中打印)

1. 健壮性判断

2. 使用copyHead保存初始头节点,后面返回值时要用到

3. p和q指向的节点同时有值时,才能进行比较

4. 前进时的两句关键代码 

5. 如果有一个指针指向空了,将另一个直接加到currentHead后面

/**
 * Definition for singly-linked list.
 * function ListNode(val, next) 
 *     this.val = (val===undefined ? 0 : val)
 *     this.next = (next===undefined ? null : next)
 * 
 */
/**
 * @param ListNode list1
 * @param ListNode list2
 * @return ListNode
 */
var mergeTwoLists = function(list1, list2) 
    // 健壮性判断
    if(!list1) return list2 ;
    if(!list2) return list1 ;

    let p = list1;
    let q = list2;
    let currentHead = new ListNode();
    // 保存初始头节点,返回结果时要用到
    const copyHead = currentHead;
    // 两个指向的节点 都有值时,才能进行比较
    while(p !== null && q !== null) 
        if (p.val <= q.val) 
            // 将p指向的节点,加到currentHead尾巴上
            const node = new ListNode();
            node.val = p.val;
            currentHead.next = node;
            // 更新头结点
            currentHead = node;
            // 关键两句:list1指向它的后面一个节点
            list1 = list1.next;
            // 更新p的指向
            p = list1;
         else 
            // 将q指向的节点,加到currentHead尾巴上
            const node = new ListNode();
            node.val = q.val;
            currentHead.next = node;
            // 更新头节点
            currentHead = node;
            // 关键两句:list2指向它的后面一个节点
            list2 = list2.next;
            // 更新q的指向
            q = list2;
        
    
    // 如果p指向null了,将q指向的节点及其后面的全部节点,添加到currentHead尾巴上
    if (p === null) 
        currentHead.next = q;
    
    // 如果q指向了null了,将p指向的节点及其后面的全部节点,添加到currentHead尾巴上
    if(q === null) 
        currentHead.next = p;
    
    return copyHead.next;
;

以上是关于21. 合并两个有序链表简单链表双指针的主要内容,如果未能解决你的问题,请参考以下文章

LeetCode Java刷题笔记—21. 合并两个有序链表

263.LeetCode | 21. 合并两个有序链表

21. 合并两个有序链表-链表-简单

力扣21.合并两个有序链表

21. 合并两个有序链表 Java

21. 合并两个有序链表 Java