刷题笔记01:从5月份开始刷算法题了,今天起正式记录一下自己的一些刷题历程。
leetcode21题:
解题思路:
1.整体思路:本来想着用两个辅助指针,分别指向两个链表的头,然后移动指针进行比较,较大的插到较小的后面,最后发现实现起来,不是那么容易;
2.最终采用一个第三方结构(为方便添加,选择列表)来存储两个链表比较之后得到的次序,包含两个链表的所有节点值。然后让链表l1的各节点更换这些值,需要注意的是。l1的长度是肯定小于列表的,所以更换的过程中需要在到达l1的末尾后,开辟新节点接上去。下面为详细步骤及一些注意点:
1.首先,在编写程序时,要考虑特殊情况和一般情况,将特殊情况过滤掉,主要针对一般情况写控制逻辑。
2.过滤特殊情况的程序最好写在主程序中,这里就是将两个链表分别可能为空及都为空的情况滤掉;
3.写排序的逻辑,这里能进入该程序说明两个链表都不为空,要记得这个前提条件;
4.要得到两个链表的排序情况,则需要传入的形参有,两个链表的指针,两个辅助指针,以及存放排序结果的列表
5.排序开始,将l1的第一个节点值与l2第一个节点值进行比较,会有三个结果即大于小于等于,每个结果都对应不同的处理方法,总体思想就是递归,即每次的判断方法是一样的
6.注意点:因为l1与l2不是等长的,所以在递归鄂出口条件判别处,要将各种情况考虑到。即当两个链表都便利到最后时,return;当l1到尾,l2还有时,要将l2剩余的元素添加到列表,再return;当l2到尾,l1还有时,同理。
代码:
/**
* 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; }
* }
*/
```java
class Solution {
public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
ListNode p1;
ListNode p2;
ListNode p3;
p1=l1;
p2=l2;
p3=l1;
List<Integer> list=new ArrayList<Integer>();
if(l1==null&&l2!=null){
return l2;
}else if(l1!=null&&l2==null){ return l1;}
else{
Solution.newList(l1,l2,list,p1,p2);
for(int i=0;i<list.size();i++){
if(p3.next==null&&i!=list.size()-1){
ListNode ln=new ListNode();
p3.next=ln;
}
p3.val=list.get(i);
p3=p3.next;
}
}
return l1;
}
public static void newList(ListNode l1,ListNode l2,List list,ListNode p1,ListNode p2){
if(p1==null&&p2==null){return;}
else if(p1==null&&p2!=null){
while(true){
list.add(p2.val);
if(p2.next==null){
break;
}
p2=p2.next;
}
return;
}else if(p1!=null&&p2==null){
while(true){
list.add(p1.val);
if(p1.next==null){
break;
}
p1=p1.next;
}
return;
}
else if(p1.val<p2.val){
list.add(p1.val);
p1=p1.next;
newList(l1,l2,list,p1,p2);
}else if(p1.val==p2.val){
list.add(p1.val);
list.add(p2.val);
p1=p1.next;
p2=p2.next;
newList(l1,l2,list,p1,p2);
}
else if(p1.val>p2.val){
list.add(p2.val);
p2=p2.next;
newList(l1,l2,list,p1,p2);
}
}
}