1、自己
我的第一个觉得好的方法是:为两个链各自设置一个指针,开始都指向第一个,然后比较,谁小就并入,指针向后。
这个想法占空间,但是时间会剩下来。
我的第二个想法就是:以第一个链为主,将第二个链的数挨个和第一个链的数进行比较(注意:不是从头比较,因为本来链就是按照大小的顺序,所以可以从前一个数的位置开始往后比较)。
这个想法时间会久,但是剩空间。
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
//判断为空
if(l1 == null && l2 == null){
return null;
}
//
ListNode p1 = null; //指向新链的开头
ListNode p2 = null; //指向新链的末尾
if((l1 != null) && (l2 == null || l1.val <= l2.val)){
p1 = l1;
p2 = l1;
l1 = l1.next;
}
else if(l1 == null || l1.val > l2.val){
p1 = l2;
p2 = l2;
l2 = l2.next;
}
while(l1 != null || l2 != null){
if((l1 != null) && (l2 == null || l1.val <= l2.val)){
p2.next = l1;
p2 = l1;
l1 = l1.next;
continue;
}
if((l2 != null) && (l1 == null || l1.val > l2.val)){
p2.next = l2;
p2 = l2;
l2 = l2.next;
continue;
}
}
return p1;
}
}
提交错误:
1、还是在逻辑判断上出现了问题,但是这个方法的逻辑判断很复杂,很难一次性写对。主要是在输入值为null的时候判断较为复杂
2、递归
看了一下官方的解答,使用的是递归的方法。感觉那个逻辑上的判断要简单的很多,代码看起来也更加的简介。
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
if(l1 == null){
return l2;
}else if(l2 == null){
return l1;
}else if(l1.val <= l2.val){
l1.next = mergeTwoLists(l1.next, l2);
return l1;
}else{
l2.next = mergeTwoLists(l1, l2.next);
return l2;
}
}
}
提交问题:
感觉递归算法总是写的时候没有头绪,也知道是自己调用自己,但是总是想不好。
3、迭代
迭代法就有点像我的第二种想法,就是l1不动,把l2的元素依次插入
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
ListNode Prehead = new ListNode(-1); //设置头节点,用来最后返回
ListNode pre = Prehead; //新链表的指针
while(l1 != null && l2 != null){ //注意,这里用的是并且,也就是说只要有一个是空了就跳出while循环
if(l1.val <= l2.val){
pre.next = l1;
l1 = l1.next;
pre = pre.next;
}else{
pre.next = l2;
l2 = l2.next;
pre = pre.next;
}
}
pre.next = l1 == null ? l2 : l1; //这个是跟前面的while里的判断呼应,这里就把while里还剩下的加入链表
return Prehead.next; //注意这个不能返回他本身,因为第一个是自己构造出来的
}
}
提交问题:
1、少了pre指针向后挪动的操作
总结:使用迭代的方法,有几个步骤的处理感觉很巧妙
1、while循环里只要有人是null,就跳出循环。然后在后面把不是null的都放到链表的后面。这样做的一大好处是省去了while里面复杂的判断,完美的解决了这样的问题。
2、还有就是最后的返回指针,这个比我自己做的要好。不会说先进行一个新的,再开始其他的。