合并两个列表算法(java实现)
题目
将两个升序链表合并成一个新的升序链表。
输入:1->2->4,1->3->4
输出:1->1->2->3->4->4
分析
1.迭代实现
1.建立一个临时结点方便处理
2.不断比较L1,L2的值,哪个小就放到临时结点的后面
3.其中一个为空后,将不空的直接放在最后
过程:
List1:1->2->4
List2:1->3->4
最终列表:临时结点->
策略:谁小往临时节点后加谁,一样的话附加List1的元素
比较:List1的第一个元素1 和 List2中的第一个元素1
结果:相同
List1:2->4
List2:1->3->4
最终列表:临时结点->1
List1:2->4
List2:3->4
最终列表:临时结点->1->1
List1:4
List2:3->4
最终列表:临时结点->1->1->2
…
时间复杂度 O(N)
空间复杂度 O(1)
2.递归实现
假设方法mergeTwoList_2
可以完成这个任务,mergeTwoList_2
需要传入两个列表的列表头。假设传入了两个列表,直接比较这两个列表的第一个元素的大小,决定这个节点放置哪个元素,之后将剩余的排序任务交给mergeTwoList_2
去完成;之后,还需要考虑一个问题,就是终止条件是什么,那自然是其中一个列表为空,直接将剩余的列表加入到最终列表中。
时间复杂度 O(N)
空间复杂度 O(N)
是不是感觉这么写有大病,性能没提升,反而浪费了空间,确实。。。但是这个方法的好处,就是代码量一般要少于其他方法,在有些题目中容易想到,说道性能,真的不咋的。
代码
工具类代码
节点代码
public class ListNode {
int val;
ListNode next;
ListNode(){}
ListNode(int val){
this.val=val;
}
ListNode(int val,ListNode next){
this.val=val;
this.next=next;
}
}
打印工具类代码
public class UtilListNode {
public static void printNode(ListNode head) {
if (head == null) {
System.out.println("Empty!");
return;
}
StringBuilder sb = new StringBuilder();
while (head != null) {
sb.append(head.val);
if (head.next != null) {
sb.append("-->");
}
head = head.next;
}
System.out.println(sb.toString());
}
}
迭代法代码
public class mergeTwoList {
public ListNode mergeTwoList(ListNode l1, ListNode l2) {
ListNode p = new ListNode();
ListNode head = p;
while (l1 != null && l2 != null) {
if (l1.val <= l2.val) {
p.next = l1;
l1 = l1.next;
} else {
p.next = l2;
l2 = l2.next;
}
p = p.next;
}
p.next = (l1 == null ? l2 : l1);
return head.next;
}
public void test() {
ListNode a1 = new ListNode(1);
ListNode a2 = new ListNode(2);
ListNode a3 = new ListNode(4);
ListNode b1 = new ListNode(1);
ListNode b2 = new ListNode(3);
ListNode b3 = new ListNode(4);
a1.next = a2;
a2.next = a3;
b1.next = b2;
b2.next = b3;
UtilListNode.printNode(a1);
UtilListNode.printNode(b1);
UtilListNode.printNode(mergeTwoList(a1, b1));
}
public static void main(String[] args) {
mergeTwoList t=new mergeTwoList();
t.test();
}
}
递归法代码
public class mergeTwoList {
public ListNode mergeTwoList_2(ListNode l1, ListNode l2) {
if (l1 == null || l2 == null) {
return l1 == null ? l2 : l1;
}
if (l1.val<=l2.val){
l1.next=mergeTwoList_2(l1.next,l2);
return l1;
}else {
l2.next=mergeTwoList_2(l1,l2.next);
return l2;
}
}
public void test() {
ListNode a1 = new ListNode(1);
ListNode a2 = new ListNode(2);
ListNode a3 = new ListNode(4);
ListNode b1 = new ListNode(1);
ListNode b2 = new ListNode(3);
ListNode b3 = new ListNode(4);
a1.next = a2;
a2.next = a3;
b1.next = b2;
b2.next = b3;
UtilListNode.printNode(a1);
UtilListNode.printNode(b1);
UtilListNode.printNode(mergeTwoList_2(a1, b1));
}
public static void main(String[] args) {
mergeTwoList t = new mergeTwoList();
t.test();
}
}