自從上次推送了鏈表的基本操作後,現在就來試着寫一寫比較複雜的東西。
比如,合併兩個有序的鏈表:
L1: 1 1 2 4
L2: 1 2 3 5 6
我們需要的鏈表是:1 1 1 2 2 3 4 5 6
思考一下,有兩種簡單粗暴辦法:
第一種:
我們建立一個鏈表頭head,比較prev1的值和prev2的值,誰小誰放在head後面,然後位置往後移(不創建新結點,會破壞原鏈表);
class Solution {
public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
if(l1 == null){
return l2;
}
if(l2 == null){ //空鏈表情況
return l1;
}
ListNode prev1=l1;
ListNode prev2=l2;
ListNode head=null;//新鏈表頭
ListNode tail=null;//新鏈表尾
while(prev1 !=null && prev2 !=null){
if(prev1.val <= prev2.val){
if(head == null){
head=prev1; //第一個節點,給head和tail同時賦值
tail=prev1;
prev1=prev1.next;
}
else{
tail.next=prev1;
tail=tail.next;
prev1=prev1.next;
}
}
else{
if(head == null){
head=prev2;
tail=prev2;
prev2=prev2.next;
}
else{
tail.next=prev2;
tail=tail.next;
prev2=prev2.next;
}
}
}
if(prev1 == null){ //看誰結束了,放在後面
tail.next=prev2;
return head;
}
if(prev2 == null){
tail.next=prev1;
return head;
}
return head;
}
}
第兩種:思想是一樣的,但是我們不破壞原鏈表,新建結點重新創建。
class Solution {
public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
if(l1 == null ){
return l2;
}
if(l2 == null ){
return l1;
}
ListNode prev1=l1;
ListNode prev2=l2;
ListNode head=new ListNode(-1);
ListNode cur=head;
while(prev1 !=null && prev2 !=null){
if(prev1.val >= prev2.val){
ListNode Node=new ListNode(prev2.val);
cur.next=Node;
cur=cur.next;
prev2=prev2.next;
}
else{
ListNode Node=new ListNode(prev1.val);
cur.next=Node;
cur=cur.next;
prev1=prev1.next;
}
}
if(prev1 == null){
cur.next=prev2;
return head.next;
}
if(prev2 ==null){
cur.next=prev1;
return head.next;
}
return head.next;
}
}
可以看得出來,第二種代碼比較短,也好理解;
(0ms是第一種,1ms是第二種)