LeetCode(121)买卖股票的最佳时机
今天是小呆刷题的第 14 天,今天的题目是:力扣(LeetCode)的第 121 题,买卖股票的最佳时机
题目要求
给定一个数组prices,它的第i个元素prices[i]表示一支给定股票第i天的价格。
你只能选择某一天买入这只股票,并选择在未来的某一个不同的日子卖出该股票。设计一个算法来计算你所能获取的最大利润。
返回你可以从这笔交易中获取的最大利润。如果你不能获取任何利润,返回0。
示例:
12345678输入:[7,1,5,3,6,4]输出:5解释:在第 2 天(股票价格 = 1)的时候买入,在第 5 天(股票价格 = 6)的时候卖出,最大利润 = 6-1 = 5 。 注意利润不能是 7-1 = 6, 因为卖出价格需要大于买入价格;同时,你不能在买入前卖出股票。输入:prices = [7,6,4,3,1]输出:0解释:在这种情况下, 没有交易完成, 所以最大利润为 0。
提示:
1 <= prices.length <= 10^5
0 <= prices[i] <= 10^4
解题思路这道题首先我们要明确一个股票买卖的规则就是:当天 ...
LeetCode(136)只出现一次的数字
今天是小呆刷题的第 13 天,今天的题目是:力扣(LeetCode)的第 136 题,只出现一次的数字
题目要求
给你一个非空整数数组nums,除了某个元素只出现一次以外,其余每个元素均出现两次。找出那个只出现了一次的元素。
你必须设计并实现线性时间复杂度的算法来解决此问题,且该算法只使用常量额外空间。
示例:
12345输入:nums = [2,2,1]输出:1输入:nums = [4,1,2,1,2]输出:4
提示:
1 <= nums.length <= 3 * 10^4
-3 * 10^4 <= nums[i] <= 3 * 10^4
除了某个元素只出现一次以外,其余每个元素均出现两次。
解题思路这道题小呆首先想到的是哈希集合,因为题目中讲到:除了某个元素只出现一次以外,其余每个元素均出现两次。所以我们不能直接数组去重,但是我们可以利用Set集合存储的值唯一这个特性,去遍历数组,如果遍历过程中哈希集合中存储过当前项,那说明当前元素不唯一,直接删掉。循环结束后,就得出了那个不唯一的元素。
123456789101112131415/** * @ ...
LeetCode(485)最大连续1的个数
今天是小呆刷题的第12天,今天的题目是:力扣(LeetCode)的第485题,最大连续1的个数
题目要求
给定一个二进制数组nums, 计算其中最大连续1的个数。
示例:
123输入:nums = [1,1,0,1,1,1]输出:3解释:开头的两位和最后的三位都是连续 1 ,所以最大连续 1 的个数是 3.
提示:
1 <= nums.length <= 10^5
nums[i]不是0就是1.
解题思路这道题还是比较简单的,题目要求计算最大连续的1的个数,那我们每遇到1个1,就计数一次,如果遇到0,说明中断了,就重新计数,最后返回计数的值就可以了。由于重新计数会覆盖之前的计数,所以还需要额外的一个变量来储存返回值。老规矩,哪怕再简单的题,一图胜千言。
12345678910111213141516/** * @param {number[]} nums * @return {number} */var findMaxConsecutiveOnes = function(nums) { let count = 0 ...
LeetCode(70)爬楼梯
今天是小呆刷题的第11天,今天的题目是:力扣(LeetCode)的第70题,爬楼梯
题目要求
假设你正在爬楼梯。需要n阶你才能到达楼顶。
每次你可以爬1或2个台阶。你有多少种不同的方法可以爬到楼顶呢?
示例:
12345输入:n = 2输出:2解释:有两种方法可以爬到楼顶。1. 1 阶 + 1 阶2. 2 阶
提示:
0 <= n <= 45
解题思路第一眼看上去,这道题小呆并没有看出什么名堂,所以我们根据示例,写一下输入和输出,看看能否找出规律:
n = 1输出1,有1种方法:1
n = 2输出2,有2种方法:1 + 1, 2
n = 3输出3,有3种方法: 1 + 1 + 1, 1 + 2, 2 + 1
n = 4输出5,有5种方法:1 + 1 + 1 + 1, 1 + 1 + 2, 1 + 2 + 1, 2 + 1 + 1, 2 + 2
观察输出,嘿,这不是跟昨天做的斐波那契数一样嘛。那就当做个复习吧~ 先写递归:
12345678/** * @param {number} n * @return {number} ...
LeetCode(509)斐波那契数
今天是小呆刷题的第10天,今天的题目是:力扣(LeetCode)的第509题,斐波那契数
题目要求
斐波那契数(通常用F(n)表示)形成的序列称为斐波那契数列。该数列由0和1开始,后面的每一项数字都是前面两项数字的和。也就是:
F(0) = 0,F(1) = 1
F(n) = F(n - 1) + F(n - 2),其中 n > 1
给定n,请计算F(n)。
示例:
123输入:n = 2输出:1解释:F(2) = F(1) + F(0) = 1 + 0 = 1
提示:
0 <= n <= 30
解题思路大名鼎鼎的斐波那契数,也是面试中经常会考的一道算法题。这道题的解法有很多种,最简单的就是使用递归。毕竟怎么写题目要求都已经给出来了,所以很快就能写出来一个解法:
n < 2,返回n
F(n) = F(n - 1) + F(n - 2)
12345678/** * @param {number} n * @return {number} */var fib = functio ...
LeetCode(20)有效的括号
今天是小呆刷题的第9天,今天的题目是:力扣(LeetCode)的第20题,有效的括号
题目描述
给定一个只包括'(',')','{','}','[',']'的字符串s,判断字符串是否有效。
有效字符串需满足:
左括号必须用相同类型的右括号闭合。
左括号必须以正确的顺序闭合。
每个右括号都有一个对应的相同类型的左括号。
示例:
12345输入:s = "()"输出:true输入:s = "(]"输出:false
提示:
1 <= s.length <= 10^4
s仅由括号'()[]{}'组成
解题思路小呆做这道题的时候,5分钟内没解出来,果断看评论区和题解。这道题的主流思路是用栈来解决,由于括号都是成对出现的,所以我们可以让左侧的括号入栈,当遇到右侧的括号时,出栈匹配,能匹配到,就接着循环,直到所有括号都匹配完或者出现不匹配为止。在JavaScript中我们很容易用数组 ...
LeetCode(344)反转字符串
今天是小呆刷题的第8天,今天的题目是:力扣(LeetCode)的第344题,反转字符串
题目要求
编写一个函数,其作用是将输入的字符串反转过来。输入字符串以字符数组s的形式给出。
不要给另外的数组分配额外的空间,你必须原地修改输入数组、使用O(1)的额外空间解决这一问题。
示例:
12输入:s = ["h","e","l","l","o"]输出:["o","l","l","e","h"]
提示:
1 <= s.length <= 10^5
s[i]都是ASCII码表中的可打印字符
解题思路这道题,由于题目要求原地修改数组,小呆首先想到了前几天一直在用的双指针算法。具体思路如下:
设置left,right两个指针,一个指向数组头部,一个指向数组尾部
循环条件是left <= right
设置一个temp变量,用于left和right交换时的中转站
交换left ...
LeetCode(21)合并两个有序链表
今天是小呆刷题的第7天,今天的题目是:力扣(LeetCode)的第21题,合并两个有序链表
题目要求
将两个升序链表合并为一个新的升序链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。
示例:
12输入:l1 = [1,2,4], l2 = [1,3,4]输出:[1,1,2,3,4,4]
提示:
两个链表的节点数目范围是[0, 50]
-100 <= Node.val <= 100
l1和l2均按非递减顺序排列
解题思路这道题,5分钟内我没写出来。思路其实是有的,就是比较两个链表的头节点,把小的拿出来放前面,然后去比对剩下的两个链表,依次类推,但是问题是,思路有,但不知道该怎么写,这其实也是我刷题过程中最难受的。看了题解,用递归比较好实现。
比较两个链表节点的val值,将值较小的节点往前排
用值较小的节点的next节点,与另一个链表的节点比较,依次类比
两个链表的任意一方到达尾部,直接返回另一方即可
具体过程用gif图辅助理解一下:
1234567891011121314151617181920212223/** * Definition fo ...
LeetCode(206)反转链表
今天是小呆刷题的第6天,今天的题目是:力扣(LeetCode)的第206题,反转链表
题目要求
给你单链表的头节点head ,请你反转链表,并返回反转后的链表。
示例:
12输入:head = [1,2,3,4,5]输出:[5,4,3,2,1]
提示:
链表中节点的数目范围是[0, 5000]
-5000 <= Node.val <= 5000
解题思路关于链表和数组的题目,小呆还是优先考虑是否可以用双指针算法解决,毕竟最近刷的几道题都与双指针有关。由于链表之间是由next相连,所以反转链表其实就是把next的指向反转。那如何将next指向反转的呢?一共有3步:
链表的尾部节点的next一定指向null,所以我们初始化两个指针prev,curr,让其一个指向null,一个指向链表头head
进入循环,终止条件为curr !== null表示链表已经循环完毕
由于反转next会断掉当前链表,所以创建一个临时变量next,指向curr.next,防止反转next找不到路
将curr.next指向prev,然后将prev指向curr,最后将curr指向next
最 ...
JavaScript 关于闭包的理解
对于前端的同学来说,闭包这个词一定在无数的面试过程中被问到过,小呆也不例外。早些年有些公司甚至会把理解闭包当成区分初级、中级甚至高级前端工程师的一个方式。在被问到什么是闭包的时候,有些同学会回答:“闭包就是函数内部嵌套并返回一个函数”,果真如此吗?一起来复习一下闭包的知识吧。
知识点
理解闭包
闭包的应用
理解闭包闭包的定义关于对闭包的定义,一千个读者有一千个哈姆雷特,MDN Doc文档、《你不知道的JavaScript》、《JavaScript高级程序设计第3版》各自的定义都大不相同:
闭包是一个函数以及其捆绑的周边环境状态(lexical environment, 词法环境)的引用的组合。换而言之,闭包让开发者可以从内部函数访问外部函数的作用域。在JavaScript中,闭包会随着函数的创建而被同时创建。—— MDN Doc文档
当函数可以记住并访问所在的词法作用域时,就产生了闭包,即使函数是在当前词法作用域之外执行。 —— 《你不知道的JavaScript》
闭包是指有权访问另一个函数作用域中的变量的函数。—— 《JavaScript高级程序设计第3版》
初看这 ...