本文參考自《劍指offer》一書,代碼采用Java語言。
題目
輸入兩個遞增排序的鏈表,合並這兩個鏈表並使新鏈表中的結點仍然是按照遞增排序的。
思路
遞歸實現:合並過程中,每次都是從兩個鏈表中找出較小的一個來鏈接,因此可以采用遞歸來實現:當任意一個鏈表為null時,直接鏈接另一個鏈表即可;其余情況只需要在兩個鏈表中找出較小的一個結點進行鏈接,該結點的next值繼續通過遞歸函數來鏈接。
非遞歸實現:非遞歸實現比較容易想到,直接進行分情況討論即可,要稍微注意下后面代碼中頭結點的賦值過程。
測試算例
1.功能測試(兩個鏈表有多個或一個結點;結點值相同、不同)
2.特殊測試(任意一個或者兩個鏈表的頭結點為null)
Java代碼
//題目:輸入兩個遞增排序的鏈表,合並這兩個鏈表並使新鏈表中的結點仍然是按
//照遞增排序的。
public class MergeSortedLists {
public class ListNode{
int val;
ListNode next=null;
public ListNode(int val) {
this.val=val;
}
}
/*
* 遞歸版本
*/
public ListNode merge(ListNode list1,ListNode list2) {
if(list1==null) return list2;
if(list2==null) return list1;
if(list1.val<list2.val) {
list1.next=merge(list1.next, list2);
return list1;
}else {
list2.next=merge(list1, list2.next);
return list2;
}
}
/*
* 非遞歸
*/
public ListNode merge2(ListNode list1,ListNode list2) {
if(list1==null) return list2;
if(list2==null) return list1;
ListNode dummyHead=new ListNode(0); //不能為null
ListNode p=dummyHead;
while(list1!=null && list2!=null){
if(list1.val<list2.val){
p.next=list1;
list1=list1.next;
}else{
p.next=list2;
list2=list2.next;
}
p=p.next;
}
if(list1==null)
p.next=list2;
else
p.next=list1;
return dummyHead.next;
}
}
收獲
1.遞歸還是不夠熟悉,第一反應想到的還是非遞歸實現。注意每次操作相同時,要立即考慮到可以采用遞歸來進行實現。
2.遞歸實現時,需要注意鏈接的問題。
