面試題分享 --- 合併兩個單向鏈表

  背景:這是我在上海的一次面試遇到的,在ShowMeBug這個平臺白板編程,題目不是很難,主要考研的是白板編程的能力和邊界測試的細節。當時我寫了兩個思路,我記錄下來給大家分享。

題目描述

  有兩個有序的單鏈表,Node head1和Node head2,寫一個方法將這兩個有序鏈表合併爲一個並返回。

解題思路:

一、遞歸思路
  由於鏈表天生就是遞歸的數據結構,因此這個題目使用遞歸的方法解決很容易。思路用圖表示如下:
開始時候取出兩個鏈表中頭結點較小的那個結點,然後繼續對剩下的兩個鏈表繼續進行合併操作。
在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述

實現代碼如下
public static Node mergeNode(Node head1, Node head2) {
        if(head1 == null && head2 == null) {
            return null;
        }
        if(head1 == null) {
            return head2;
        }
        if(head2 == null) {
            return head1;
        }
        Node head = head1.val <= head2.val ? head1 : head2;
        if(head == head1) {
            head.next = mergeNode(head.next,head2);
        }else {
            head.next  =mergeNode(head.next,head1);
        }
        return head;
    }

二、非遞歸思路:
利用四個指針來實現,一個是pre指針,一個是next指針,另外兩個是cur1和cur2指針,它們分別是什麼含義呢?看下圖:
在這裏插入圖片描述
每次講cur1指針的值與cur2指針的值進行比較,將較小的放在pre指針的後面,只要注意結點指針的指向即可。

實現代碼如下
public static Node mergeNode2(Node head1,Node head2) {
        Node head = head1.val <= head2.val ? head1 : head2;
        Node cur1 = head.next;
        Node cur2 = head == head1 ? head2 : head1;
        Node pre = head;
        Node next = cur2.next;
        while (cur1 != null && cur2 != null) {
            if(cur1.val <= cur2.val) {
                pre.next = cur1;
                pre = cur1;
                cur1 = cur1.next;
            }else {
                cur2.next = cur1;
                pre.next = cur2;
                pre = cur2;
                cur2 = next;
                next = cur2.next;
            }
        }
        pre.next = cur1 == null ? cur2 : cur1;
        return head;

    }

完整代碼

public class MergeTwoLinkedList {

    public static Node createNode(int[] nums) {
        Node temp = new Node(nums[0]);
        Node head = temp;
        for (int i=1; i<nums.length; i++) {
            temp.next = new Node(nums[i]);
            temp = temp.next;
        }
        return head;
    }

    public static Node mergeNode(Node head1, Node head2) {
        if(head1 == null && head2 == null) {
            return null;
        }
        if(head1 == null) {
            return head2;
        }
        if(head2 == null) {
            return head1;
        }
        Node head = head1.val <= head2.val ? head1 : head2;
        if(head == head1) {
            head.next = mergeNode(head.next,head2);
        }else {
            head.next  =mergeNode(head.next,head1);
        }
        return head;
    }

    public static Node mergeNode2(Node head1,Node head2) {
        Node head = head1.val <= head2.val ? head1 : head2;
        Node cur1 = head.next;
        Node cur2 = head == head1 ? head2 : head1;
        Node pre = head;
        Node next = cur2.next;
        while (cur1 != null && cur2 != null) {
            if(cur1.val <= cur2.val) {
                pre.next = cur1;
                pre = cur1;
                cur1 = cur1.next;
            }else {
                cur2.next = cur1;
                pre.next = cur2;
                pre = cur2;
                cur2 = next;
                next = cur2.next;
            }
        }
        pre.next = cur1 == null ? cur2 : cur1;
        return head;

    }

    public static void main(String[] args) {
        int[] nums1 = new int[] {0,0,1,3,5,7,9};
        int[] nums2 = new int[] {2,4,6,8,10};
        Node head1 = createNode(nums1);
        Node head2 = createNode(nums2);
        Node result = mergeNode2(head1,head2);
        System.out.println(result.toString());
    }

}

class Node {
    int val;
    Node next;

    public Node(int val) {
        this.val = val;
    }

    @Override
    public String toString() {
        Node head = this;
        StringBuilder sb = new StringBuilder();
        while (head != null && head.next!= null) {
            sb.append(head.val + "->");
            head = head.next;
        }
        if (head != null) {
            sb.append(head.val);
        }
        return sb.toString();
    }
}

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