背景:這是我在上海的一次面試遇到的,在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();
}
}