1、自己
我的第一個覺得好的方法是:爲兩個鏈各自設置一個指針,開始都指向第一個,然後比較,誰小就併入,指針向後。
這個想法佔空間,但是時間會剩下來。
我的第二個想法就是:以第一個鏈爲主,將第二個鏈的數挨個和第一個鏈的數進行比較(注意:不是從頭比較,因爲本來鏈就是按照大小的順序,所以可以從前一個數的位置開始往後比較)。
這個想法時間會久,但是剩空間。
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
//判斷爲空
if(l1 == null && l2 == null){
return null;
}
//
ListNode p1 = null; //指向新鏈的開頭
ListNode p2 = null; //指向新鏈的末尾
if((l1 != null) && (l2 == null || l1.val <= l2.val)){
p1 = l1;
p2 = l1;
l1 = l1.next;
}
else if(l1 == null || l1.val > l2.val){
p1 = l2;
p2 = l2;
l2 = l2.next;
}
while(l1 != null || l2 != null){
if((l1 != null) && (l2 == null || l1.val <= l2.val)){
p2.next = l1;
p2 = l1;
l1 = l1.next;
continue;
}
if((l2 != null) && (l1 == null || l1.val > l2.val)){
p2.next = l2;
p2 = l2;
l2 = l2.next;
continue;
}
}
return p1;
}
}
提交錯誤:
1、還是在邏輯判斷上出現了問題,但是這個方法的邏輯判斷很複雜,很難一次性寫對。主要是在輸入值爲null的時候判斷較爲複雜
2、遞歸
看了一下官方的解答,使用的是遞歸的方法。感覺那個邏輯上的判斷要簡單的很多,代碼看起來也更加的簡介。
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
if(l1 == null){
return l2;
}else if(l2 == null){
return l1;
}else if(l1.val <= l2.val){
l1.next = mergeTwoLists(l1.next, l2);
return l1;
}else{
l2.next = mergeTwoLists(l1, l2.next);
return l2;
}
}
}
提交問題:
感覺遞歸算法總是寫的時候沒有頭緒,也知道是自己調用自己,但是總是想不好。
3、迭代
迭代法就有點像我的第二種想法,就是l1不動,把l2的元素依次插入
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
ListNode Prehead = new ListNode(-1); //設置頭節點,用來最後返回
ListNode pre = Prehead; //新鏈表的指針
while(l1 != null && l2 != null){ //注意,這裏用的是並且,也就是說只要有一個是空了就跳出while循環
if(l1.val <= l2.val){
pre.next = l1;
l1 = l1.next;
pre = pre.next;
}else{
pre.next = l2;
l2 = l2.next;
pre = pre.next;
}
}
pre.next = l1 == null ? l2 : l1; //這個是跟前面的while裏的判斷呼應,這裏就把while裏還剩下的加入鏈表
return Prehead.next; //注意這個不能返回他本身,因爲第一個是自己構造出來的
}
}
提交問題:
1、少了pre指針向後挪動的操作
總結:使用迭代的方法,有幾個步驟的處理感覺很巧妙
1、while循環裏只要有人是null,就跳出循環。然後在後面把不是null的都放到鏈表的後面。這樣做的一大好處是省去了while裏面複雜的判斷,完美的解決了這樣的問題。
2、還有就是最後的返回指針,這個比我自己做的要好。不會說先進行一個新的,再開始其他的。