Offer 驾到,掘友接招!我正在参与2022春招打卡活动,点击查看活动详情。
前言
今天的第二题难度为简单,题目涉及到链表,关于链表的题目做过很多,大多数都是递归解题,今天提供一种新的迭代解题的思路。
每日一题
今天的第二题题目是 21. 合并两个有序链表,难度为简单
- 将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。
示例 1:
输入:l1 = [1,2,4], l2 = [1,3,4]
输出:[1,1,2,3,4,4]
示例 2:
输入:l1 = [], l2 = []
输出:[]
示例 3:
输入:l1 = [], l2 = [0]
输出:[0]
提示:
- 两个链表的节点数目范围是 [0, 50]
- -100 <= Node.val <= 100
- l1 和 l2 均按 非递减顺序 排列
题解
非递归解法-迭代解法
因为题目给出的链表本身就是升序排列的,所以这道题稍微简单,非递归的方式就是我们要自己去建立链表,每次去对比两个升序链表的结点大小,将小的那一个添加到我们自己建立的链表当中,并且移动链表结点,继续重复上面的操作。
如上图所示,我们只要建立一个新的链表,在后面不断地添加结点,那么最后的得到的链表除了第一个结点以外就是答案。
当然还会有特殊情况,比如上面这一种,一个链表比另一个少很多,那么我们在其中一个链表走到null的时候,就要左上判断,让另一个链表剩下的值都接到后面去。
像上面这个这样,在某一个列表空了之后,要把另个一个全都添加进去。
/**
* @param {ListNode} list1
* @param {ListNode} list2
* @return {ListNode}
*/
var mergeTwoLists = function (list1, list2) {
const myNodeList = new ListNode(-1);
let preNode = myNodeList;
while (list1 != null || list2 != null) {
if (list1 != null && list2 != null) {
if (list1.val <= list2.val) {
preNode.next = list1;
list1 = list1.next;
} else {
preNode.next = list2;
list2 = list2.next;
}
preNode = preNode.next;
} else {
if (list1 != null) {
preNode.next = list1;
list1 = list1.next;
preNode = preNode.next;
}
if (list2 != null) {
preNode.next = list2;
list2 = list2.next;
preNode = preNode.next;
}
}
}
return myNodeList.next; //返回prehead.next
};
递归解法
递归解法的思路和上面也是一样的,我们每次都会去判断当前的两个链表的下一个结点是否为空,是的话就会将另一个链表返回,都不为空则去判断两个链表当前结点值的大小,将小的那一边作为当前结点,后面的结点则将 小的那边已经另外一边作为参数进行递归,最后就能够得到全部的一个链表。
/**
* Definition for singly-linked list.
* function ListNode(val, next) {
* this.val = (val===undefined ? 0 : val)
* this.next = (next===undefined ? null : next)
* }
*/
/**
* @param {ListNode} list1
* @param {ListNode} list2
* @return {ListNode}
*/
var mergeTwoLists = function (list1, list2) {
if (list1 === null) {
return list2;
} else if (list2 === null) {
return list1;
} else if (list1.val < list2.val) {
list1.next = mergeTwoLists(list1.next, list2);
return list1;
} else {
list2.next = mergeTwoLists(list1, list2.next);
return list2;
}
};