1.思路
- 和合并两个数组的思路差不多
- 只要有一个为空,立马跳出循环去处理第二个
2.易错点 - 不搞虚拟头时
- 一进来,两个头结点为空,返回null结束函数,后面代码不执行
- 考虑没进入循环的情况 - > 一开始就有1个头结点为空 -> 根本就没有进入循环
- 处理正常跳出 -> 有一个为null / 有两个为null -> 必须是2个if,不能是if-else
若一开始就有一个人为空,循环没进去,则newhead和cur都为空,cur不能.next
3.代码 - 不搞虚拟头时
/** * Definition for singly-linked list. * public class ListNode { * int val; * ListNode next; * ListNode() {} * ListNode(int val) { this.val = val; } * ListNode(int val, ListNode next) { this.val = val; this.next = next; } * } */ class Solution { public ListNode mergeTwoLists(ListNode list1, ListNode list2) { //最后记得看是谁剩余了东西 //两个链表一起遍历 //新头法 //万一这两个头都是空的 if(list1 ==null && list2==null){ return null; } //原本的两个链表不需要维护,直接用各自的头结点进行遍历 ListNode newhead=null; //新头 ListNode cur=null; //维护新头的节点 while(list1 !=null && list2!=null){ if(list1.val<list2.val){ if(newhead==null){ newhead=list1; cur=newhead; }else{ cur.next=list1; cur=cur.next; } list1=list1.next; }else{ if(newhead==null){ newhead=list2; cur=newhead; }else{ cur.next=list2; cur=cur.next; } list2=list2.next; } } //此时,是正常的跳出循环的 if(list1==null){ //如果一开始就有人为空,循环根本就没有进去的话 。cur==null,不可以.next if(newhead==null){ return list2; } cur.next=list2; //处理正常跳出循环,一个人为空。连接 } if(list2==null){ //如果一开始就有人为空,循环根本就没有进去的话 if(newhead==null){ return list1; } cur.next=list1; //处理正常跳出循环,一个人为空。连接 } return newhead; } }
这是不搞虚拟头时
4.代码 - 设虚拟头时
特点:
不用管真实的新头是否存在,可以直接接在虚拟头后面 -> 省了好多代码量
不用判断新头head1还是head2,小的接在虚拟头后面就完事了
不用判断是否进入了循环,谁还有元素,往新链表后面接就完事了
总结:写前想一想要不要用虚拟头、不用虚拟头时要注意什么