将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。
示例 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
均按 非递减顺序 排列
思路
我做的时候用了一点投机取巧的办法,大致想法就是先把输入的两个单链表分别存在两个ArrayList
里(类似C++的vector
,不定长数组),然后合并两个ArrayList
,再用sort
函数给合并好后的ArrayList
排个序,最后再将ArrayList
转成单链表输出。
主要的逻辑操作就是1.遍历单链表(由单链表存储到ArrayList
的过程);2.创建单链表(由ArrayList
存储到单链表的过程)。
如果想不明白这两个操作的话,可以动动手在草稿纸上画一画,会清楚一些。
【注】由ArrayList
存储到单链表时,返回的是单链表的首个节点,功能函数mergeTwoLists
读入的也是两个单链表的首个节点。
代码
public class Solution {
public static class ListNode {//为了方便本地调试调用内部类,我写了静态的
//实际提交时可以不写ListNode类
int val;
ListNode next;
ListNode() {}
ListNode(int val) { this.val = val; }
ListNode(int val, ListNode next) { this.val = val; this.next = next; }
}
public ArrayList<Integer> listToArray(ListNode l1) {
ArrayList<Integer> arrayList = new ArrayList<Integer>();
if(l1!=null) {
do{
arrayList.add(l1.val);
l1 = l1.next;
}while(l1!=null);
}
return arrayList;
}
public ListNode arrayToList(ArrayList<Integer> array) {
ListNode head = new ListNode();
if(array.size()!=0) {
ListNode pre = new ListNode();//记录前驱
for(int i=0;i<array.size();i++) {
ListNode p = new ListNode();
p.val = array.get(i);
p.next = null;
if(i>0) pre.next = p;
pre = p;
if(i==0) head = pre;//因为前驱pre会不停后移,所以第一次要先记录下头结点head的位置
}
}
else head = null;
return head;
}
public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
ArrayList<Integer> arrayList1 = listToArray(l1);
ArrayList<Integer> arrayList2 = listToArray(l2);
for(int i=0;i<arrayList2.size();i++) {
arrayList1.add(arrayList2.get(i));
}
Collections.sort(arrayList1);
ListNode answear = arrayToList(arrayList1);
return answear;
}
}