解题思路:
1.非递归解法:类似于归并排序第二步合并的步骤,设置三个指针p1、p2、p3。p1指向第一个链表的头结点,p2指向第二个链表的头结点,p3指向第三个链表的头结点。首先确定第三个链表的表头指针list3Head。然后比较p1和p2所指向的值哪个小,就选择小的那个加入到第三个链表中,同时将指向较小元素的指针后移,p3也后移,重复上述操作,直到遍历完某一个链表为止。若另一个链表中此时还剩元素未遍历,则将剩余元素全部添加到新链表中。
2.递归解法:设置合并后链表的头结点pMergeHead初始值为null,从list1和list2的头结点开始,哪个链表指向的元素小,则将pMergeHead指向该节点,然后从较小的链表的下一个元素开始,递归地调用merge()方法。
/** * 剑指offer面试题17 合并两个排序的链表 */ class ListNode { int val; ListNode next = null; public ListNode(int val) { this.val = val; } } public class Solution { /** * 非递归实现 */ public static ListNode Merge(ListNode list1,ListNode list2) { if (list1 == null && list2 == null) { return null; } if (list1 == null) { return list2; } if (list2 == null) { return list1; } //list和list2都不为空的情况下,利用归并排序中归并的思想 ListNode p1 = list1; ListNode p2 = list2; ListNode list3Head = null; //一开始需要确定新链表头指针的位置 if (list1.val < list2.val) { list3Head = new ListNode(list1.val); p1 = p1.next; } else { list3Head = new ListNode(list2.val); p2 = p2.next; } ListNode p3 = list3Head; while (p1 != null && p2 != null) { if (p1.val < p2.val) { //如果p1指向元素比p2小,则将p2指向元素加入到新链表中 ListNode temp = new ListNode(p1.val); p3.next = temp; p1 = p1.next; p3 = p3.next; } else { ListNode temp = new ListNode(p2.val); p3.next = temp; p2 = p2.next; p3 = p3.next; } } while (p1 != null) { ListNode temp = new ListNode(p1.val); p3.next = temp; p1 = p1.next; p3 = p3.next; } while (p2 != null) { ListNode temp = new ListNode(p2.val); p3.next = temp; p2 = p2.next; p3 = p3.next; } return list3Head; } /** * 递归实现 */ public static ListNode Merge_Recursive(ListNode list1,ListNode list2){ if (list1 == null && list2 == null) { return null; } if (list1 == null) { return list2; } if (list2 == null) { return list1; } ListNode pMergeHead = null; if (list1.val < list2.val) { pMergeHead = list1; pMergeHead.next = Merge(list1.next, list2); } else { pMergeHead = list2; pMergeHead.next = Merge(list1, list2.next); } return pMergeHead; } }