描述
给定两个升序的单链表的头节点 head1 和 head2,请合并两个升序链表, 合并后的链表依然升序,并返回合并后链表的头节点。
示例
输入:
5 1 2 3 4 5 6 7 8 9 10 11 12输出:
1 2 3 4 5 7 8 9 10 11 12
解题思路:
在不需要额外空间的情况下,不需要其它数据结构的帮助下,可以将两个链表分为主链表和次链表。只需通过判断将次链表合并到主链表,合并返回主链表的头节点即可。
- 判断边界条件,两个链表只要有一个链表是空的,直接返回另外一个链表的头节点即可。
- 确认主链表和次链表。要比较两个链表的第一个节点的大小,谁小谁就是头节点。
- 确认cu1和cur2。cur1代表的遍历主链表的变化节点。cur2代表的遍历主链表的变化节点。
- 确认pre。pre代表上一次比较完的cur1和cur2的最小的值,用来指向cur1或cur2。
- 开始遍历比较。如果cur1<=cur2,pre就等于cur1,cur1下移。cur1>cur2,就让pre指向cur2,cur2指向主链表剩余的部分,也就是cur1。
- 连接上剩余链表。只要有一个链表遍历完,只需要将pre指向剩余部分。
import java.util.Scanner;
class Node{
public int value;
public Node next;
public Node(int value){
this.value=value;
}
}
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
// 注意 hasNext 和 hasNextLine 的区别
String[] n1=in.nextLine().split(" ");
String[] num1=in.nextLine().split(" ");
String[] n2=in.nextLine().split(" ");
String[] num2=in.nextLine().split(" ");
Node node1=transForNode(num1);
Node node2=transForNode(num2);
//Node nodeF=addList1(node1,node2);//方法1
Node nodeF=merge(node1,node2);//方法2
show(nodeF);
}
//打印链表
public static void show(Node head){
while(head!=null){
System.out.print(head.value+" ");
head=head.next;
}
System.out.println();
}
//数组转链表
public static Node transForNode(String[] nums) {
Node head = new Node(Integer.parseInt(nums[0]));
Node cur = head;
for(int i = 1; i < nums.length; i++) {
cur.next = new Node(Integer.parseInt(nums[i]));
cur = cur.next;
}
return head;
}
//方法1:将次链表上的节点合并到主链表上
public static Node merge(Node head1,Node head2){
if(head1==null||head2==null){
return head1!=null?head1:head2;
}
Node head=head1.value<head2.value?head1:head2;//谁小谁就是头
//规范一下cur1在主链表上,cur2在次链表上
Node cur1= head==head1?head1:head2;
Node cur2= head==head1?head2:head1;
Node pre=null;//表示加入的新节点
Node next=null;
while(cur1!=null&&cur2!=null){
if(cur1.value<=cur2.value){
pre=cur1;
cur1=cur1.next;
}else{
next=cur2.next;
pre.next=cur2;//pre指向次链表的首节点
cur2.next=cur1;//连接上主链表的后面部分链表
pre=cur2;//更新pre为新加入的cur2
cur2=next;//cur2更新
}
}
//将次链表剩余部分加入即可
pre.next=cur1==null?cur2:cur1;
return head;
}
}