力扣第21题合并两个有序链表
题目:
将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。
思路:
1、首先建立一个两个节点指向同一个内存地址,之后让一个节点去移动去拼接节点
2、依次比较两个链表的值,较小的那个节点就要被移动的那个节点指向,最终返回不动的那个节点的next。
代码:
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public ListNode mergeTwoLists(ListNode list1, ListNode list2) {
ListNode preHead= new ListNode(0);
ListNode prev= head;
while(list1!=null&&list2!=null){
if (list1.val <= list2.val) {
prev.next = list1;
prev= prev.next;
list1 = list1.next;
} else {
prev.next = list2;
prev= prev.next;
list2 = list2.next;
}
}
if(list1==null){
prev.next=list2;
}else{
prev.next=list1;
}
return preHead.next;
}
}
图示:
刚开始的初始节点对应的内存地址以及他们的关系
第一次循环结果 :第一次循环执行了
//由于实际操作的是内存地址,prev的内存是0x00000000,因为list1的值等于list2,prev的下一个节点是list1,
//这行代码导致了0x00000000指向了list1的第一个节点0x00000001,最终返回的链表现在是preHead->0x00000000->0x00000001
prev.next = list1;
//那么这个就导致了prev的内存地址指向了list1的第一个节点 0x00000001
prev = prev.next;
//那么此时list1节点到了链表的第二个节点位置0x00000001
list1 = list1.next;
第二次循环结果:执行了
//刚刚的prev指向内存0x00000001,现在执行这行语句prev的下一个节点内存地址就是list2,那么0x00000001连接到了0x00000004,
//整个返回的链表变成了preHead->0x00000000->0x00000001->0x00000004
prev.next = list2;
//prev此时指向0x00000004
prev= prev.next;
//list2往下移动,此时list2地址为0x00000005
list2 = list2.next;
第三次循环结果:执行了
//此时list1的值比较小,那么prev的下一个节点就是list1的内存地址,
//此时最终返回的链表是preHead->0x00000000->0x00000001->0x00000004->0x00000002
prev.next = list1;
//那么这个就导致了prev的内存地址指向 0x00000002(prev始终指向最终返回链表的末尾,因为是它需要去移动拼接)
prev = prev.next;
//那么此时list1节点到了链表的第三个节点位置0x00000003
list1 = list1.next;
那么往后按照此流程以此类推:最终的结果:
最终返回preHead.next那么就是preHead指向的链表
这个题目还有一种解法,那就是递归,递归不用创建新的节点,它就是直接将两个链表重新让节点断开连接上正确顺序的节点,最终返回。
代码:
/**
* 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;
}
if(l2 == null) {
return l1;
}
if(l1.val <= l2.val) {
l1.next = mergeTwoLists(l1.next, l2);
return l1;
} else {
l2.next = mergeTwoLists(l1, l2.next);
return l2;
}
}
}
如果l1比l2当前值小,然后l1的下一个节点与l2当前节点比较,l2比较小,那么此时l1.next就得指向l2的当前节点,然后l2的下一个节点与l1比较,以此类推下去,最终l1和l2会按照顺序连接起来。
算法专题:力扣LeetCode算法专题