21. 合并两个有序链表

21. 合并两个有序链表

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、还有就是最后的返回指针,这个比我自己做的要好。不会说先进行一个新的,再开始其他的。

 

 

 

 

 

 

 

 

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章