两个有序链表的合并

两个有序链表的合并

给定两个有序链表的头节点head1和head2,
返回合并之后的大链表,要求依然有序
例子:1 -> 3 -> 3 -> 5 -> 7 2 -> 2 -> 3 -> 3 -> 7
返回:1 -> 2 -> 2 -> 3 -> 3 -> 3 -> 3 -> 5 -> 7 -> 7
 
思路:
1.这个算是常见题,实际使用中也会常用到。思路就是想办法把一个链表串进去。
将两个链表穿针引线起来,举个例子:
1.两个链表的头节点值更小的那个,作为头节点。例如上图中的H1的1节点作为头节点。
 
 
cur1: 指向小头的下一个节点。
cur2: 直接指向大头。
cur1和cur2的值谁更小,pre的next就指向谁,同时谁往下移动一个,同时pre来到指向下一个的位置。
while循环体中执行完第一次后,变化如下:
再次比较cur1和cur2谁小,5小,pre.next指向5,同时cur1移到到下个位置,同时pre顺着自己方向漂向下个位置,如图:
继续:
cur1已经到null了,cur2在9,跳出while循环,pre的next指向9,结束。
如果9的后面还有13,15,16...,不会再遍历了,7的next指向9就直接结束。
 

总结:

1.这样图解的方式虽然慢,但是绝对是对你来讲最有帮助的,从图开始画,别心浮气躁,用简单的例子吧整个流程串明白了,再去想抽象化的事。
2.这些题其实不涉及很难的算法,不是要多难想,就是手熟的问题,但是把手练熟了之后,在这个过程中扣逻辑的能力会提升。
3.你写的越想吐的时候,你能力提高的越快。就是纯coding。
 
 
代码实现:
package com.cy.class04;

/**
 * @description com.cy.class04
 * @author: chengyu
 * @date: 2025-05-02 15:24
 */
public class Code06_MergeTwoSortedLinkedList {

    public static class ListNode {
        public int val;
        public ListNode next;
    }

    /**
     * head: 两个两笔头节点值的大小决定了谁是小头。更小的那个是小头。
     * cur1:小头的下一个是cur1。cur1别从头出发,从下一个开始出发
     * cur2: 大头的第一个是cur2
     */
    public static ListNode mergeTwoLists(ListNode head1, ListNode head2) {
        if (head1 == null || head2 == null) {
            return head1 == null ? head2 : head1;
        }
        ListNode head = head1.val <= head2.val ? head1 : head2;
        ListNode cur1 = head.next;
        ListNode cur2 = head == head1 ? head2 : head1;
        ListNode pre = head;
        while (cur1 != null && cur2 != null) {
            if (cur1.val <= cur2.val) {
                pre.next = cur1;
                cur1 = cur1.next;
            } else {
                pre.next = cur2;
                cur2 = cur2.next;
            }
            pre = pre.next;
        }
        pre.next = cur1 != null ? cur1 : cur2;
        return head;
    }
}
 
 
--
posted on 2025-05-02 16:14  有点懒惰的大青年  阅读(94)  评论(0)    收藏  举报