LeetCode(83)删除排序链表中的重复元素
今天要练习的题目是:力扣(LeetCode)的第83题,删除排序链表中的重复元素
题目要求
给定一个已排序的链表的头head,删除所有重复的元素,使每个元素只出现一次。返回已排序的链表。
示例:
12输入:head = [1,1,2,3,3]输出:[1,2,3]
提示:
链表中节点数目在范围[0, 300]内
-100 <= Node.val <= 100
题目数据保证链表已经按升序排列
解题思路由于链表已经按升序排列,所以值相同的两个节点肯定相连。这道题的本质其实与昨天的题一样,只不过数据结构由数组变成了链表。我们依然可以使用双指针算法来解决。
依旧用一张git图来帮助理解代码在循环过程中,及最后的slow.next = null的作用。
123456789101112131415161718192021222324/** * Definition for singly-linked list. * function ListNode(val, next) { * this.val = (val===undefined ? 0 : val ...
LeetCode(26)删除有序数组中的重复项
如果说面试中小呆最怕什么,那一定是算法。在以往的业务开发中,遇到需要算法的地方屈指可数。加上大学期间并没有系统的学过数据结构与算法,导致算法成为了小呆的一个非常明显的短板。曾经有一段时间突击过数据结构与算法的学习,遗憾的是并没有坚持下来。不过以后有空的时候还是要多练习练习,毕竟现在的面试全是八股文和算法题。
今天要练习的题目是:力扣(LeetCode)的第26题,删除有序数组中的重复项
题目要求
给你一个升序排列的数组nums,请你原地删除重复出现的元素,使每个元素只出现一次,返回删除后数组的新长度。元素的相对顺序应该保持一致。
由于在某些语言中不能改变数组的长度,所以必须将结果放在数组nums的第一部分。更规范地说,如果在删除重复项之后有k个元素,那么nums的前k个元素应该保存最终结果。
将最终结果插入nums的前k个位置后返回k。
不要使用额外的空间,你必须在 原地修改输入数组并在使用O(1)额外空间的条件下完成。
示例:
123输入:nums = [1,1,2]输出:2, nums = [1,2,_]解释:函数应该返回新的长度 2 ,并且原数组 nums 的前两个元素被修 ...
手写一个带取消功能的延迟函数
最近在看一些优秀文章的时候,关注到了若川,他组织了一个若川视野X源码共读的活动,每周一起学习200行源码,我觉得这是一个非常不错的机会,不管是对于前端新人,还是工作多年的老手,都能够有一个提升。自然而然我也加入到这个活动里面,这是加入此活动的第一篇笔记。
关于手写一个带取消功能的延迟函数,我在两年前的一次面试中遇到过,这算是一个由浅入深的系列问题,从简单的延迟,到随机延迟,再到取消功能和最后的取消请求。当时没能答的很好,这次刚好源码共读第18期就是一个delay函数的实现,借此机会也复习一下相关知识。
知识点
实现一个完整的延迟函数
AbortController如何使用
了解Axios取消请求
实现一个完整的延迟函数我们来模拟一场面试,来学习如何实现一个完整的延迟函数。前提:面试询问了我一些关于Promise的知识。接着面试官说:小呆你好,我想实现一个闹钟,希望可以在任意时间后打印出“起床啦”,但是我希望你能用Promise实现。我心想,这还不容易,您瞧好嘞!
基本功能12345// 面试官想要的效果(async () => { await delay(1 ...
JavaScript 关于作用域的理解
如果你对作用域、作用域链、词法作用域等概念还傻傻分不清楚,那就看看这篇文章吧。了解作用域相关知识,也有助于理解闭包、执行上下文等JS核心知识。跟随小呆的视角,一起来复习一下吧。
知识点
理解JavaScript的执行过程
理解什么是作用域 & 作用域链
理解什么是词法作用域
理解JavaScript的执行过程在说作用域之前,我们要知道JavaScript的执行过程是分为两个阶段的:代码的编译阶段和代码的执行阶段。编译阶段由编译器完成,将代码翻译成可执行代码,这个阶段作用域规则会确定。执行阶段由引擎完成,主要任务是执行可执行代码,执行上下文在这个阶段创建。
作用域和执行上下文是完全不同的两个概念。一个在代码的编译阶段发生,一个在代码的执行阶段发生。
编译阶段词法分析编译器首先会将由字符组成的字符串分解成有意义的代码块,这些代码块被称为词法单元(token)。
1var a = 2;
以上面的代码为例,通常会被分解成词法单元:如 var, a, =, 2, ;,这些词法单元组成了一个词法单元流数组。
12345678910111213141516171819202122[ ...
JavaScript this到底指向谁
相信很多前端同学在曾经的面试过程中,都经历过this指向的灵魂拷问。对于基础知识掌握不扎实的同学,this指向似乎是一门玄学,有人说this的绑定是在代码创建阶段完成的,有人说this的绑定是在代码执行阶段完成的,那真相到底是什么,跟着我一起复习一下吧。
知识点
this的绑定是在什么阶段完成的
this的绑定规则
this绑定的优先级
特殊环境的this指向
this的绑定是在什么阶段完成的如果你了解JavaScript执行上下文(对JS执行上下文不了解的同学推荐先看我的另一篇文章《理解执行上下文》),那么你一定能脱口而出:this的绑定是在执行阶段完成。我们先来回顾一下不同的执行上下文是如何被创建出来的:
JavaScript引擎先创建全局执行上下文(this在此阶段被绑定到GlobalObject)
全局执行上下文入栈
代码开始执行,遇到函数调用,创建函数执行上下文(this在此阶段根据上下文动态绑定)
执行函数内部代码,执行完毕,函数执行上下文出栈
我们都知道全局执行上下文的this指向的是window对象(浏览器下)。那函数的执行上下文,this绑定的依据是什么?答 ...
JavaScript 关于闭包的理解
对于前端的同学来说,闭包这个词一定在无数的面试过程中被问到过,小呆也不例外。早些年有些公司甚至会把理解闭包当成区分初级、中级甚至高级前端工程师的一个方式。在被问到什么是闭包的时候,有些同学会回答:“闭包就是函数内部嵌套并返回一个函数”,果真如此吗?一起来复习一下闭包的知识吧。
知识点
理解闭包
闭包的应用
理解闭包闭包的定义关于对闭包的定义,一千个读者有一千个哈姆雷特,MDN Doc文档、《你不知道的JavaScript》、《JavaScript高级程序设计第3版》各自的定义都大不相同:
闭包是一个函数以及其捆绑的周边环境状态(lexical environment, 词法环境)的引用的组合。换而言之,闭包让开发者可以从内部函数访问外部函数的作用域。在JavaScript中,闭包会随着函数的创建而被同时创建。—— MDN Doc文档
当函数可以记住并访问所在的词法作用域时,就产生了闭包,即使函数是在当前词法作用域之外执行。 —— 《你不知道的JavaScript》
闭包是指有权访问另一个函数作用域中的变量的函数。—— 《JavaScript高级程序设计第3版》
初看这 ...
理解JavaScript执行上下文
众所周知,前端是一个低门槛,进阶难的一个岗位。而JavaScript又是前端中的重中之重,不管是出于面试还是提升自己,都得学习并掌握JavaScript程序如何在内部执行的。而理解执行上下文和执行栈对于理解其他JavaScript概念(如:提升、作用域和闭包)至关重要。
知识点
什么是执行栈
什么是执行上下文
执行上下文的发展阶段
如何创建执行上下文
什么是执行栈在学习执行上下文之前,我们先了解一些前置知识:
我们都知道汽车最重要的部分是:引擎(发动机)。JavaScript也是如此,**JavaScript引擎是运行JavaScript代码的发动机**。
而执行栈,就是JavaScript引擎用来管理执行上下文的数据结构。代码执行期间的所有执行上下文,都会被存储到执行栈中。栈的特点是后入先出,所以先入栈的执行上下文会在最后才出栈。
执行栈(也叫调用栈),具有LIFO(后入先出)结构,用于存储在代码执行期间创建的所有执行上下文
什么是执行上下文了解了什么是执行栈之后,接下来我们看一下什么是执行上下文:
JavaScript标准,把一段代码(包括函数)执行所需的所有信息定义为 ...
JavaScript new运算符做了什么
new运算符,想必大家都不陌生,在工作当中肯定用到过。而且也是面试当中经常问的一道面试题,那你有了解过new运算符背后的原理和如何实现一个new吗?一起来复习一下吧!
知识点
new运算符的作用与原理
如何实现一个new运算符
new运算符的作用与原理
new运算符创建一个用户定义的对象类型的实例或具有构造函数的内置对象的实例。
通俗的来讲,new运算符的作用就是通过构造函数来创建一个带有原型链的实例对象。或者你可以这样理解:就像小时候的中秋节,家里会用刻有小兔子的月饼的模具,生产好多个印有小兔子的月饼的过程。是不是就有那味儿了~
举个例子:中秋节妈妈交给我一个任务,需要我做5个印有小兔子的月饼。我们用代码来实现一下:
12345var moonCake = { id: 1, fill: 'wuren', type: 'rabbit', info: function() { console.log('eat') } }var moonCake2 = { id: 2, f ...
一起露营吧
“春来也无信,春去也无踪,眼睛一眨,在北平市内,春光就会同飞马似的溜过”,郁达夫曾这样幽默的描述过北京的春天。是的,北京的春天总是很短,刚脱掉羽绒服,似乎还没细细的感受春天到来,说不定就得穿上短袖,打上遮阳伞。正因为北京的春天短,所以才要抓住时机,去感受一下北京的春天。
三年的口罩,隔绝了我们与大自然的拥抱,解封后的第一个春天,是时候出去走走了。刚好小萌的小伙伴组织了一次自驾露营,借着这个机会,去好好感受一下春天的味道。
我们这次露营的地点选在了怀柔区的白河湾生态营地,从家里出发全程 95Km,单程在 2 个小时左右。似乎是周末+郊区的原因,路上的车不算多,路两边的小树苗也才刚刚抽枝。
进入怀柔区后,车渐渐的就多了起来。路两边开满了画,甚是好看。还有很多观景台,能近距离的观赏一些未经开发的长城。不过由于观景台人还挺多,我们也没有停留。
终于到达目的地了,小伙伴们也忙碌了起来,搭天幕,架烧烤架,零食水果满满一大桌。我先偷个懒拍几张美美的照片~
吃吃喝喝总是少不了的,户外烧烤肯定是必备的项目之一了。小伙伴们的手艺也是棒棒哒~
吃饱喝足,小伙伴们有的打牌(输了要表演节目的哟),有的钓 ...
根据起止日期返回中间所有月份
题目描述:
题目:给定一个开始日期’2022-08’,一个结束日期’2023-02’
要求:实现一个函数getMonthArray,返回开始日期到结束日期中间的所有月份[‘2022-09’, ‘2022-10’, ‘2022-11’, …, ‘2023-01’]
知识点
字符串的拼接与截取
数字类型与字符串类型的相互转换
月份与年的计算
实现思路
根据入参截取出开始年份、月份。
计算两个日期实际相差几个月。
循环拼接日期,放入到数组中,需要注意月份大于12时,需重置为1,同时年份+1
1234567891011121314151617181920212223function getMonthArray(startDate, endDate) { let startYear = parseInt(startDate.split('-')[0]) let startMonth = parseInt(startDate.split('-')[1]) let yearDiff = parseInt(endDate.s ...