劍指offer面試題17:合併兩個排序的鏈表


 題目:輸入兩個遞增排序的鏈表,合併這兩個鏈表並使新鏈表中的節點人是按照遞增排序的。
解題思路:兩個鏈表分別都已是有序的了,遍歷鏈表的時候只要比較兩個鏈表當前位置大小,取出最小的添加到新鏈表中。node

能夠有遞歸、循環兩種方式來解決。測試

  1 package Solution;
  2 
  3 
  4 public class No17MergeSortedLists {
  5 
  6     public static class ListNode {
  7         int data;
  8         ListNode next;
  9 
 10         public ListNode() {
 11 
 12         }
 13 
 14         public ListNode(int value, ListNode next) {
 15             this.data = value;
 16             this.next = next;
 17         }
 18     }
 19 
 20     public static void print(ListNode head) {
 21         if (head == null)
 22             System.out.println("當前鏈表爲空");
 23         while (head != null) {
 24             System.out.print(head.data + ",");
 25             head = head.next;
 26         }
 27         System.out.println();
 28     }
 29    //遞歸方式合併兩個排序的鏈表
 30     public static ListNode merge(ListNode head1, ListNode head2) {
 31         if (head1 == null)
 32             return head2;
 33         if (head2 == null)
 34             return head1;
 35         ListNode mergedHead = null;
 36         if (head1.data < head2.data) {
 37             mergedHead = head1;
 38             mergedHead.next = merge(head1.next, head2);
 39         } else {
 40             // 若是兩個節點的值相同,返回第二個
 41             mergedHead = head2;
 42             mergedHead.next = merge(head1, head2.next);
 43         }
 44         return mergedHead;
 45     }
 46     //依次比較兩個鏈表的當前結點,添加到新鏈表中
 47     public static ListNode mergeSortedList(ListNode head1, ListNode head2) {
 48         if (head1 == null)
 49             return head2;
 50         if (head2 == null) {
 51             return head1;
 52         }
 53         ListNode newHead = null;
 54         ListNode newNode = null;
 55         ListNode list1 = head1;
 56         ListNode list2 = head2;
 57         // 找到新的頭結點
 58         if (list1.data < list2.data) {
 59             newHead = list1;
 60             list1 = list1.next;
 61         } else {
 62             newHead = list2;
 63             list2 = list2.next;
 64         }
 65         newNode = newHead;
 66         // 合併其餘節點
 67         while (list1 != null && list2 != null) {
 68             if (list1.data < list2.data) {
 69                 newNode.next = list1;
 70                 list1 = list1.next;
 71             } else {
 72                 newNode.next = list2;
 73                 list2 = list2.next;
 74             }
 75             newNode = newNode.next;
 76         }
 77         // 有一條鏈表合併完,則把剩下的另外一條鏈表直接合併到新鏈條末尾
 78         if (list1 == null) {
 79             newNode.next = list2;
 80         } else {
 81             newNode.next = list1;
 82         }
 83         return newHead;
 84     }
 85 
 86     public static void main(String[] args) {
 87         ListNode node1 = new ListNode(7, null);
 88         ListNode node2 = new ListNode(4, node1);
 89         ListNode node3 = new ListNode(3, node2);
 90         ListNode head1 = new ListNode(1, node3);
 91 
 92         ListNode node5 = new ListNode(8, null);
 93         ListNode node6 = new ListNode(6, node5);
 94         ListNode node7 = new ListNode(4, node6);
 95         ListNode head2 = new ListNode(2, node7);
 96         // 測試含有相同值得兩個對各節點的鏈表的合併,合併後head1和merged1都指向合併後的新鏈表的頭結點
 97         // ListNode merged1 = merge(head1, head2);
 98         // print(merged1);
 99         // // 測試含有一個null頭指針的鏈表的合併,因爲head2指向上一步合併後的新鏈表的第二個節點,因此輸出的節點個數爲總個數-1
100         // print(merge(head2, null));
101         // // 測試兩個鏈表中只有一個節點
102         // print(merge(null, new ListNode(10, null)));
103         ListNode merged1 = mergeSortedList(head1, head2);
104         print(merged1);
105         // 測試含有一個null頭指針的鏈表的合併,因爲head2指向上一步合併後的新鏈表的第二個節點,因此輸出的節點個數爲總個數-1
106         print(mergeSortedList(head2, null));
107         // 測試兩個鏈表中只有一個節點
108         print(mergeSortedList(null, new ListNode(10, null)));
109     }
110 
111 }
相關文章
相關標籤/搜索