面试算法TOP101——链表合并

141 阅读1分钟

0.合并两个已经排好序的链表

迭代写法:

public ListNode Merge(ListNode list1,ListNode list2) {
        if (list1 == null || list2 == null) {
            return list1 != null ? list1 : list2;
        }
        ListNode res = new ListNode(-1);
        ListNode cur = res;
        while (list1 != null && list2 != null) {
            if (list1.val < list2.val) {
                cur.next = list1;
                list1 = list1.next;
            } else {
                cur.next = list2;
                list2 = list2.next;
            }
            cur = cur.next;
        }
        if (list1 != null || list2 != null) {
            cur.next = list1 != null ? list1 : list2;
        }
        return res.next;
    }

迭代思想:用一个指针在两个链表之间移动,每次移动到较小元素位置上
时间复杂度O(N+M)
空间复杂度O(1)

递归写法:

public ListNode Merge(ListNode list1,ListNode list2) {
        if (list1 == null || list2 == null) {
            return list1 != null ? list1 : list2;
        }
        if (list1.val < list2.val) {
            list1.next = Merge(list1.next, list2);
        }
        else {
            list2.next = Merge(list1, list2.next);
        }
        return list1.val < list2.val ? list1 : list2;
    }

递归思想:递归返回两个链表中剩下的当前元素较小的部分
时间复杂度O(N+M)
空间复杂度O(1)

1.合并K个自增排序的链表

采用分治的思想,将k个链表两两合并,再对合并后的结果进行合并,两个链表合并的实现和上面一样,主要是如何划分链表集合,这次采用二分划分:

public ListNode merge(ListNode list1, ListNode list2) {
        if (list1 == null || list2 == null) {
            return list1 != null ? list1 : list2;
        }
        ListNode res = new ListNode(-1);
        ListNode cur = res;
        while (list1 != null && list2 != null) {
            if (list1.val < list2.val) {
                cur.next = list1;
                list1 = list1.next;
            } else {
                cur.next = list2;
                list2 = list2.next;
            }
            cur = cur.next;
        }
        if (list1 != null || list2 != null) {
            cur.next = list1 != null ? list1 : list2;
        }
        return res.next;
    }
    
    ListNode divideList(ArrayList<ListNode> lists, int left, int right) {
        if (left > right) {
            return null;
        }
        else if (left == right) {
            return lists.get(left);
        }
        int mid = (left + right) / 2;
        return merge(divideList(lists, left, mid), divideList(lists, mid+1, right));
    }
    
    public ListNode mergeKLists(ArrayList<ListNode> lists) {
        return divideList(lists, 0, lists.size()-1);
    }

时间复杂度O(NlogK)
空间复杂度O(N*K)