[LeetCode-Java演習]21。2つの順序付きリンクリストをマージする(単純)

1.タイトルの説明

ここに画像の説明を挿入

2.問題解決のアイデア

アイデア1:再帰
次のように、2つのリンクリストでマージ操作を再帰的に定義できます(空のリンクリストなどの境界条件を無視します)。

list1 [0] + merge(list1 [1:]、list2)list1 [0] <list2 [0]
list2 [0] + merge(list1、list2 [1:])それ以外の場合

つまり、2つのリンクリストのヘッド値が小さいノードが、残りの要素のマージ操作の結果とマージされます。
アルゴリズム
上記の再帰的プロセスを直接モデル化すると同時に、境界条件を考慮する必要があります。

l1またはl2が最初から空のリンクリストである場合、マージする操作はないため、空でないリンクリストを返すだけで済みます。それ以外の場合は、リンクリストのヘッドノードの値が小さい方をl1とl2のどちらかを判別してから、結果に追加する次のノードを再帰的に決定する必要があります。2つのリンクリストのいずれかが空の場合、再帰は終了します。

アイデア2:反復
反復法を使用して、上記のアルゴリズムを実装できます。l1とl2の両方が空のリンクリストでない場合、l1とl2のどちらがリンクリストのヘッドノードの値が小さいかを判断し、値が小さいノードを結果に追加します。ノードが結果に追加された場合、対応するリンクリストにあります。のノードは1ビット戻ります。

アルゴリズム
最初に、センチネルノードのプリヘッドを設定します。これにより、最後にマージされたリンクリストに簡単に戻ることができます。前のポインタを維持し、次のポインタを調整する必要があります。次に、l1またはl2がnullを指すまで、次のプロセスを繰り返します。l1の現在のノードの値がl2以下の場合、l1の現在のノードを前のノードの後ろに接続してポインターを移動します。 l1の1ビット後方。それ以外の場合は、l2についても同じことを行います。どの要素に従うかに関係なく、prevを1ビット後方に移動する必要があります。

ループの終わりでは、l1とl2の最大1つが空ではありません。2つの入力リンクリストは順番に並んでいるため、どちらのリンクリストが空でなくても、そこに含まれるすべての要素は、以前にマージされたリンクリストのすべての要素よりも大きくなります。これは、空でないリンクリストをマージされたリンクリストの後ろに接続して、マージされたリンクリストに戻るだけでよいことを意味します。

3.コードの実装

アイデア1のコード:

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;
        }

    }
}

アイデア2のコード:

class Solution {
    
    
    public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
    
    
        ListNode prehead = new ListNode(-1);

        ListNode prev = prehead;
        while (l1 != null && l2 != null) {
    
    
            if (l1.val <= l2.val) {
    
    
                prev.next = l1;
                l1 = l1.next;
            } else {
    
    
                prev.next = l2;
                l2 = l2.next;
            }
            prev = prev.next;
        }

        // 合并后 l1 和 l2 最多只有一个还未被合并完,我们直接将链表末尾指向未合并完的链表即可
        prev.next = l1 == null ? l2 : l1;

        return prehead.next;
    }
}

おすすめ

転載: blog.csdn.net/weixin_48683410/article/details/113616181