「这是我参与2022首次更文挑战的第9天,活动详情查看:2022首次更文挑战」
前言
每天至少一道算法题,死磕算法
今天我们终于开始学习链表了,链表题真的不是那么容易掌握
,我说的这个掌握是
- 10分钟内写出来
- 在leetcode上写,不要有代码提示
- 并且能2遍之内写对
所以大家做好心里准备,不要受打击,我们一定要有死磕的精神
为了我们方便掌握
,所以我们多探讨链表的技巧
先上一道简单的题目,来个前菜
题目
这是leetcode上的第21道题---合并两个有序链表
将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。
难度:简单
示例 1:
输入: l1 = [1,2,4], l2 = [1,3,4]
输出: [1,1,2,3,4,4]
复制代码
思路
我们前面做过一道类似的数组的题,js算法题解(第二天)---LeetCode:88.合并两个有序数组,这两个题目除了数据结构不一样,其他都非常的相似
所以解法那也非常相似了
当时的数组是从最后面开始循环的,但是链表题很难从最后面开始循环,所以我们从前开始循环
所以链表的循环我们一定要非常熟练的掌握
链表循环
let dummy = new ListNode();
// 操作cur就相当于再操作dummy,之所以在定义一个变量cur,是因为最后结果是让返回整个链表,所以返回dummy.next就可以了
let cur = dummy;
while(循环条件){
// 每次cur指向新的节点
cur=cur.next;
}
return dummy.next;
复制代码
只要牢记上面这个循环,单链表题解决轻轻松松
从题目中提取关键词
- 1.合并为一个新的升序链表,所以我们要新建一个链表变量,升序代表我们要对比题中给出的两个链表节点的大小
- 2.新的链表要通过循环的形式,把l1,l2上的节点赋值给新的节点
题解
/**
* Definition for singly-linked list.
* function ListNode(val, next) {
* this.val = (val===undefined ? 0 : val)
* this.next = (next===undefined ? null : next)
* }
*/
/**
* @param {ListNode} l1
* @param {ListNode} l2
* @return {ListNode}
*/
var mergeTwoLists = function(l1, l2) {
// 定义dummy节点
let dummy = new ListNode();
// 操作cur就相当于再操作dummy,之所以在定义一个变量cur,是因为最后结果是让返回整个链表,所以返回dummy.next就可以了
let cur = dummy;
// l1,l2相当于两个指针,l1&&l2是循环结束的条件
while(l1&&l2){
// 对比指针的数值大小
if(l1.val>l2.val){
cur.next = l2;
// 变量的修改,cur.next的指向不会变
l2 = l2.next;
}else {
cur.next = l1;
l1 = l1.next;
}
// cur重新赋值
cur=cur.next;
}
// 如果最后发现那个链表还没有为null的话,那么cur.next就指向他
cur.next=(l1?l1:l2);
return dummy.next;
};
复制代码
总结
循环链表必须要好好掌握,只有这样,我们才能更好的手撕算法,加油呀,老铁们