算法,从承认自己是一个菜鸟开始!
话不多说,让我们继续我们的算法之旅。
前言
今天我们来继续熟悉链表相关知识,合并连个有序链表,首先来看下题目要求。
21. 合并两个有序链表
将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。
示例:
输入: l1 = [1,2,4], l2 = [1,3,4]
输出: [1,1,2,3,4,4]
题目分析
这道题中提到了两个重要的核心点:有序、链表。
链表的结构如下:
class ListNode {
val: number
next: ListNode | null
constructor(val?: number, next?: ListNode | null) {
this.val = (val===undefined ? 0 : val)
this.next = (next===undefined ? null : next)
}
}
基于链表的结构,每次我们分别取出两个链表中的当前节点的值,进行比较,按照升序进行排列即可,然后继续向后移动节点再次比对,一直到链表末尾即可。
Up Code ~ 上码 ~
/**
* @method mergeTwoLists
* @description 合并两个有序链表
* @param list1 {listNode | null}
* @param list2 {listNode | null}
* @returns {ListNode | null}
*/
function mergeTwoLists(list1: ListNode | null, list2: ListNode | null): ListNode | null {
// 定义一个头结点变量存储结果
let head = null;
// 当前指针指向头结点
let currentNode = head;
// 遍历list1和list2,二者只要其中一个有值,就进行遍历处理
while (list1 || list2) {
// 设置临时变量currentListNode,接收list1和list2中的最小值
let currentListNode = null
// list1和list2的节点情况有三种
// 1. list1和list2都有值
if (list1 && list2) {
// 比较二者的值
if (list1.val < list2.val) {
// 取最小值list1节点
currentListNode = list1;
// 现在list1当前节点的值已经被使用了,需要移动指针指向list.next节点
list1 = list1.next;
} else {
// 同理,取list2节点,移动list2节点的指针到next
currentListNode = list2;
list2 = list2.next;
}
// 2. 只存在list1,比如list2链表中已经遍历完了
} else if (list1) {
// 取list1节点的值
currentListNode = list1;
// 移动指针到next
list1 = list1.next;
// 只存在list2节点,比如list1链表节点遍历完成
} else if (list2) {
// 取list2节点
currentListNode = list2;
// list2节点向下移动
list2 = list2.next;
}
// 对于头节点的处理,没有值时进行赋值操作
if (!head) {
head = currentListNode
currentNode = head;
} else {
// 当已经有值时,设置next节点指向目标节点 - 即最小值节点
currentNode.next = currentListNode;
// 移动指向指向next
currentNode = currentNode.next
}
}
// 返回头结点
return head;
};
重点在于分清楚节点的几种情况,移动节点的方式
结语
以上就是胡哥今天给大家分享的内容,喜欢的小伙伴记得点赞
、收藏
呀,关注胡哥有话说,学习前端不迷路,欢迎多多留言交流...