两个有序链表的合并
两个有序链表的合并
给定两个有序链表的头节点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;
}
}
--
浙公网安备 33010602011771号