转载请注明出处:https://blog.youkuaiyun.com/loiter2/article/details/108300456
该文章只是用来记录一下刷题过程,本文的记录和解答用的Java语言。
1、题目分析
1.1 题目描述与理解
输入两个单调递增的链表,输出两个链表合成后的链表,当然我们需要合成后的链表满足单调不减规则。
1.2 解法分析
- 归并排序
分别取两个指针指向两个链表表头,并比较大小,小的那个结点被放置在新链表的当前位置,并且指向较小结点的指针后移,同时新链表指针后移;重复上述过程,直至其中一个原始链表遍历结束,指针指向空,此时将另一个链表剩下部分直接接在新链表尾端即完成了归并排序。
时间复杂度为:O(m+n);
空间复杂度为:O(1); - 递归方法
写递归的两个关键点:1,认清递归函数的作用是什么,返回什么值,以此找到怎么缩小递归区间;2,递归终止条件。
本问题用递归方法写,递归函数的作用就是将两个排序链表合成一个排序链表,返回新链表的表头。返回值一定是当前两个链表头结点中值较小的一个,最终return该值即可;因此缩小递归区间的方法就是除去原始两个链表表头结点值较小的那个后,其余链表部分重新调用递归函数。
递归终止条件是当其中一个链表为空时,直接返回另一个链表,即是合成的新链表。
时间复杂度为:O(m+n);
空间复杂度为:O(m+n),每递归一次,递归栈都保存一个变量;
下面分别给出两种方法的代码实现。
2、代码实现
作为学习,最好看了上面的思路后,自己去实现代码,学习效果更好。
2.1 归并排序
/*
public class ListNode {
int val;
ListNode next = null;
ListNode(int val) {
this.val = val;
}
}*/
public class Solution {
public ListNode Merge(ListNode list1,ListNode list2) {
//归并排序方法
ListNode list3 = new ListNode(0);
ListNode head = list3;
while (list1 != null && list2 != null){
if (list1.val >= list2.val){
list3.next = list2;
list2 = list2.next;
} else{
list3.next = list1;
list1 = list1.next;
}
list3 = list3.next;
}
if (list1 != null) list3.next = list1;
if (list2 != null) list3.next = list2;
return head.next;
}
}
2.2 递归
/*
public class ListNode {
int val;
ListNode next = null;
ListNode(int val) {
this.val = val;
}
}*/
public class Solution {
public ListNode Merge(ListNode list1,ListNode list2) {
//递归方法
if (list1 == null) return list2;
if (list2 == null) return list1;
if (list1.val <= list2.val){
list1.next = Merge(list1.next, list2);
return list1;
}else{
list2.next = Merge(list1, list2.next);
return list2;
}
}
}