1. 程式人生 > 實用技巧 >一週刷完劍指offer-16-合併兩個有序的連結串列

一週刷完劍指offer-16-合併兩個有序的連結串列

合併兩個有序的連結串列

1. 題目描述

輸入兩個單調遞增的連結串列,輸出兩個連結串列合成後的連結串列,當然我們需要合成後的連結串列滿足單調不減規則。

2. 示例

3. 解題思路

思路:非遞迴

比較兩個連結串列的首結點,哪個小的的結點則合併到第三個連結串列尾結點,並向前移動一個結點。

步驟一結果會有一個連結串列先遍歷結束,或者沒有

第三個連結串列尾結點指向剩餘未遍歷結束的連結串列

返回第三個連結串列首結點

遞迴方法:

4. Java實現

非遞迴的實現方法:使用一個輔助的頭部節點: ListNode root = new ListNode(-1)

/*
public class ListNode {
    int val;
    ListNode next = null;
    ListNode(int val) {
        this.val = val;
    }
}*/
public class Solution {
    public ListNode Merge(ListNode list1,ListNode list2) {
        if (list1 == null){
            return list2;
        }
        if (list2 == null){
            return list1;
        }
        
        ListNode node = new ListNode(-1); // 用於儲存頭部節點
        ListNode root = node;
        
        while (list1 != null && list2 != null){
            if (list1.val < list2.val){
                node.next = list1;
                node = node.next; // 更新node節點,指向下一個
                list1 = list1.next;
            }else{
                node.next = list2;
                node = node.next;
                list2 = list2.next;
            }
        }
                // 可能某個連結串列還剩餘值,下列例子就連結串列2 會剩餘
        // 比如連結串列1: 1->2->4
        // 連結串列2:    3->5->6
        if(list1 == null){
            node.next = list2;
        }
        
        if (list2 == null){
            node.next = list1;
        }
        return root.next;
        
    }
}

使用遞迴的實現方法:

/*
public class ListNode {
    int val;
    ListNode next = null;
    ListNode(int val) {
        this.val = val;
    }
}*/
public class Solution {
    public ListNode Merge(ListNode list1,ListNode list2) {
        if (list1 == null){
            return list2;
        }
        if (list2 == null){
            return list1;
        }
        ListNode ret = null;
        if (list1.val < list2.val){
            ret = list1;
            ret.next = Merge(list1.next, list2);
        }else{
            ret = list2;
            ret.next = Merge(list1, list2.next);
        }
        
        return ret;
    }
}

5. Python實現

比較簡單的非遞迴的實現方法:

#非遞迴實現合併兩個有序的連結串列
class Solution1:
    # 返回合併後列表
    def Merge(self, pHead1, pHead2):    
        if not pHead1:
            return pHead2
        if not pHead2:
            return pHead1
        
        start = None 
        p = None 
        while pHead1 and pHead2:
            if pHead1.val <= pHead2.val:
                print(pHead1.val)
                if start is None:
                    start = p = pHead1
                else:
                    p.next = pHead1
                    p = p.next #更新p 結點
                pHead1 = pHead1.next # 更新有序連結串列的結點
            else:
                if start is None:
                    start = p = pHead2
                else:
                    p.next = pHead2
                    p = p.next 
                pHead2 = pHead2.next 
        #可能某個連結串列一直還剩值
        if not pHead1: #如果第一個連結串列都是空的話
            p.next = pHead2
        else:
            p.next = pHead1
        return start 

使用遞迴的實現方法:

# -*- coding:utf-8 -*-
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None
class Solution:
    # 返回合併後列表
    def Merge(self, pHead1, pHead2):
        # write code here
        if not pHead1: #如果一個連結串列不存在的話,返回另外一個連結串列
            return pHead2
        if not pHead2:
            return pHead1
        
        if pHead1.val <= pHead2.val:
            ret = pHead1
            ret.next = self.Merge(pHead1.next, pHead2)
        else:
            ret = pHead2
            ret.next = self.Merge(pHead1, pHead2.next)
            
        return ret 

如果您覺得本文有用,請點個“在看”