21.Merge Two Sorted Lists---《剑指offer》面试17
题目链接:https://leetcode.com/problems/merge-two-sorted-lists/description/
题目大意:
给出两个升序链表,将它们归并成一个链表,若有重复结点,都要链接上去,且新链表不新建结点。
法一:直接用数组归并的思想做,碰到一个归并一个,只是要注意链表前后结点之间的操作关系,应该弄清楚java里面引用之间的关系(此题容易面试当场写代码)。代码如下(耗时14ms):
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 /** 2 * Definition for singly-linked list. 3 * public class ListNode { 4 * int val; 5 * ListNode next; 6 * ListNode(int x) { val = x; } 7 * } 8 */ 9 class Solution { 10 public ListNode mergeTwoLists(ListNode l1, ListNode l2) { 11 ListNode l = new ListNode(0); 12 ListNode tmp = l; 13 while(l1 != null && l2 != null) { 14 if(l1.val < l2.val) { 15 l.next = l1; 16 l1 = l1.next; 17 // l = l.next; 18 } 19 else if(l1.val > l2.val) { 20 l.next = l2; 21 l2 = l2.next; 22 // l = l.next; 23 } 24 else { 25 l.next = l1; 26 l1 = l1.next; 27 l = l.next; 28 29 l.next = l2; 30 l2 = l2.next; 31 } 32 l = l.next; 33 } 34 if(l1 != null) { 35 l.next = l1; 36 } 37 else if(l2 != null) { 38 l.next = l2; 39 } 40 l = tmp; 41 return l.next; 42 } 43 }
带有测试代码:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 package problem_21; 2 3 class ListNode { 4 int val; 5 ListNode next; 6 ListNode(int x) { 7 val = x; 8 } 9 } 10 11 public class MainTest { 12 13 public void addNode(ListNode l, int num) { 14 ListNode listNode = new ListNode(num); 15 listNode.next = null; 16 if(l == null) { 17 l = listNode; 18 return; 19 } 20 ListNode tmp = l; 21 while(tmp.next != null) { 22 tmp = tmp.next; 23 } 24 tmp.next = listNode; 25 } 26 27 public static void main(String[] args) { 28 MainTest t1 = new MainTest(); 29 ListNode l1 = new ListNode(4); 30 t1.addNode(l1, 5); 31 // t1.addNode(l1, 6); 32 ListNode l2 = new ListNode(4); 33 t1.addNode(l2, 6); 34 // t1.addNode(l2, 7); 35 // while(l1 != null) { 36 // System.out.println("1val:" + l1.val); 37 // l1 = l1.next; 38 // } 39 // while(l2 != null) { 40 // System.out.println("2val:" + l2.val); 41 // l2 = l2.next; 42 // } 43 ListNode l = t1.mergeTwoLists(l1, l2); 44 while(l != null) { 45 System.out.println(l.val); 46 l = l.next; 47 } 48 } 49 50 public ListNode mergeTwoLists(ListNode l1, ListNode l2) { 51 ListNode l = new ListNode(0); 52 ListNode tmp = l; 53 while(l1 != null && l2 != null) { 54 if(l1.val < l2.val) { 55 l.next = l1;//这里在将l1结点赋值给l.next后,不能立即执行l=l1,而只能执行l1=l1.next和l=l.next(这两个位置可以调换) 56 //至于为什么,还没完全弄明白,应该跟java里面的对象的引用有关系? 57 // l = l.next; 58 l1 = l1.next; 59 } 60 else if(l1.val > l2.val) { 61 l.next = l2; 62 // l = l.next; 63 l2 = l2.next; 64 } 65 else {//测试用例中有5和5归并,结果输出为5,5,所以这里要两次连接结点 66 l.next = l1; 67 l = l.next; 68 l1 = l1.next; 69 70 l.next = l2; 71 // l = l.next; 72 l2 = l2.next; 73 } 74 l = l.next; 75 } 76 if(l1 != null) {//由于不需要新建结点,所以只需要把剩下的链表结点接上去即可。 77 l.next = l1; 78 } 79 else if(l2 != null) { 80 l.next = l2; 81 } 82 l = tmp; 83 return l.next; 84 } 85 }
法二:递归归并。代码如下(耗时11ms):
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 public static ListNode mergeTwoLists(ListNode l1, ListNode l2) { 2 if(l1 == null) { 3 return l2; 4 } 5 if(l2 == null) { 6 return l1; 7 } 8 ListNode l = null; 9 if(l1.val < l2.val) { 10 l = l1; 11 l.next = mergeTwoLists(l1.next, l2); 12 } 13 else { 14 l = l2; 15 l.next = mergeTwoLists(l1, l2.next); 16 } 17 return l; 18 }