Leetcode之鏈表(二)

目錄

11.remove-duplicates-from-sorted-list

12.remove-duplicates-from-sorted-list-ii

13.merge-two-sorted-lists

14.merge-k-sorted-lists

15.sort-list

16.insertion-sort-list

17.add-two-numbers

18.copy-list-with-random-pointer


11.remove-duplicates-from-sorted-list

題目:刪除給出鏈表中的重複元素,使鏈表中的所有元素都只出現一次。例如:給出的鏈表爲1->1->2,返回1->2.給出的鏈表爲1->1->2->3->3,返回1->2->3.

分析:找出第一個與當前結點不相等的結點即可。

   public ListNode deleteDuplicates(ListNode head) {
        ListNode cur = head;
        while(cur != null){
            ListNode curNext = cur.next;
            while(curNext != null && cur.val == curNext.val){
                curNext = cur.next;
            }
            cur.next = curNext;
            cur = curNext;
        }
        return  head;
    }

12.remove-duplicates-from-sorted-list-ii

題目:給出一個排好序的鏈表,刪除鏈表中的所有重複出現的元素,只保留原鏈表中只出現一次的元素。例如:給出的鏈表爲1->2->3->3->4->4->5, 返回1->2->5.給出的鏈表爲1->1->1->2->3,  返回2->3.

分析:見劍指offer面試題18 https://blog.csdn.net/Nibaby9/article/details/104050540

13.merge-two-sorted-lists

題目:將兩個有序的鏈表合併爲一個新鏈表,要求新的鏈表是通過拼接兩個鏈表的節點來生成的。

分析:用兩個指針標記原先鏈表的未插入的頭結點,以及一個指針標記新鏈表的最後一個結點即可。遞歸求解見劍指offer面試題25 https://blog.csdn.net/Nibaby9/article/details/104050540

   public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
        ListNode preHead = new ListNode(0);
        ListNode cur = preHead;
        ListNode head1 = l1,head2 = l2;
        while(head1 != null && head2 != null){
            if(head1.val <= head2.val){
                cur.next = head1;
                head1 = head1.next;
            }
            else{
                cur.next = head2;
                head2 = head2.next;
            }
            cur = cur.next;
        }
        if(head1 != null)
            cur.next = head1;
        else
            cur.next = head2;
        return preHead.next;
    }

14.merge-k-sorted-lists

題目:合併k個已排序的鏈表並將其作爲一個已排序的鏈表返回。分析並描述其複雜度。 

分析:採用二分歸併排序算法思想即可。

    public ListNode mergeKLists(ArrayList<ListNode> lists) {
        if(lists.size() == 0)
            return null;
        return mergeKLists(lists,0,lists.size()-1);
    }

    private ListNode mergeKLists(ArrayList<ListNode> lists, int low, int high) {
        if(low == high)
            return lists.get(low);
        int mid = (low + high) >> 1;
        ListNode head1 = mergeKLists(lists,low,mid);
        ListNode head2 = mergeKLists(lists,mid + 1,high);
        return  mergeTwoLists(head1,head2);
    }

15.sort-list

題目:在O(n log n)的時間內使用常數級空間複雜度對鏈表進行排序。

分析:採用歸併排序的思想,利用快慢指針來找出中間節點(注意找中間結點的循環條件)。

    public ListNode sortList(ListNode head) {
        if(head==null || head.next==null)
            return head;
        ListNode mid = getMid(head);
        ListNode midNext = mid.next;
        //將鏈表斷開
        mid.next = null;
        return mergeTwoLists(sortList(head),sortList(midNext));
    }

    ListNode getMid(ListNode head){
        ListNode slow = head;
        ListNode quick = head;
        while(quick.next!=null && quick.next.next!=null){
            slow = slow.next;
            quick = quick.next.next;
        }
        return slow;
    }

16.insertion-sort-list

題目:使用插入排序對鏈表進行排序。

分析:按插入排序思想排序即可。

    public ListNode insertionSortList(ListNode head) {
        if(head == null || head.next == null)
            return head;
        ListNode preHead = new ListNode(0);
        preHead.next = head;
        ListNode cur = head.next;
        head.next = null;//新鏈表!!!
        while(cur != null){
            ListNode pre = preHead,temp = cur.next;
            while(pre.next != null && cur.val > pre.next.val)
                pre = pre.next;
            cur.next = pre.next;
            pre.next = cur;
            cur = temp;
        }
        return preHead.next;
    }

17.add-two-numbers

題目:給定兩個代表非負數的鏈表,數字在鏈表中是反向存儲的(鏈表頭結點處的數字是個位數,第二個結點上的數字是百位數...),求這個兩個數的和,結果也用鏈表表示。輸入:(2 -> 4 -> 3) + (5 -> 6 -> 4);輸出: 7 -> 0 -> 8

分析:注意計算結束後是否要加上最高位1.

   public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
        if(l1 == null || l2 == null)
            return l1 == null ? l2 : l1;
        ListNode preHead = new ListNode(0);
        ListNode cur = preHead;
        int flag = 0;
        while(l1 != null && l2 != null){
            int count = l1.val + l2.val + flag;
            cur.next = new ListNode(count % 10);
            flag = count / 10;
            cur = cur.next;
            l1 = l1.next;l2 = l2.next;
        }
        while(l1 != null){
            int count = l1.val + flag;
            cur.next = new ListNode(count % 10);
            flag = count / 10;
            cur = cur.next;
            l1 = l1.next;
        }
        while(l2 != null){
            int count = l2.val + flag;
            cur.next = new ListNode(count % 10);
            flag = count / 10;
            cur = cur.next;
            l2 = l2.next;
        }
        if(flag == 1)
            cur.next = new ListNode(1);
        return preHead.next;
    }

18.copy-list-with-random-pointer

題目:現在有一個這樣的鏈表:鏈表的每一個節點都附加了一個隨機指針,隨機指針可能指向鏈表中的任意一個節點或者指向空。請對這個鏈表進行深拷貝。

分析:見劍指offer面試題35https://blog.csdn.net/Nibaby9/article/details/104050540

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