力扣学习day3

学习目标:

1.在2021年2月底刷完力扣10%题目。
2.从零开始学习C,C++,python。
3.用多种方法写出解题思路,以及理解代码。


学习内容:

11. 盛最多水的容器

网址

题目:给你 n 个非负整数 a1,a2,…,an,每个数代表坐标中的一个点 (i, ai) 。在坐标内画 n 条垂直线,垂直线 i 的两个端点分别为 (i, ai) 和 (i, 0) 。找出其中的两条线,使得它们与 x 轴共同构成的容器可以容纳最多的水。

说明:你不能倾斜容器。


思考:这道题是一道使用双指针的题目,思路大概是先使用指针start指向下标0,另一个指针end指向下标n-1,用f(0,n-1)来表示两下标下的容量,容量计算公式f(i,j)=min(ai,aj)*(j-i)。下面就方便说明了,用数学表达式的方式是最简明的方式。

首先,计算f(0,n-1),将计算出的结果存入max当中。

然后,比较a[0]和a[n-1],较小的那个数值的下标往中心靠拢,反复计算f(start,end),并与max进行比较取最大值,直到当start=end时即可结束。

最后,输出max就可以获得最大容器。

这道题的编程思想是双指针,数学思想是排除法,为啥是数值较小端移动呢?当时,我也思考过这个问题,但后面画下图像就很容易可以理解,如果移动大端,就无法排除以原大端为下标最大容器的可能;但是移动最小端,保留了以原大端为下标最大容器的可能。另外,以最小端为下标的最大容器的可能就是当前状态,此时高度最大为最小端数值,底部此时为最长。另外,如果两端相等的时候,也是一个道理,如果以这两端下标为基准的容器,此时已经是最大容器的可能,因此可以任意移动一端即可。

12. 整数转罗马数字

网址

题目:罗马数字包含以下七种字符: I, V, X, L,C,D 和 M。

字符 数值
I 1
V 5
X 10
L 50
C 100
D 500
M 1000
例如, 罗马数字 2 写做 II ,即为两个并列的 1。12 写做 XII ,即为 X + II 。 27 写做 XXVII, 即为 XX + V + II 。

通常情况下,罗马数字中小的数字在大的数字的右边。但也存在特例,例如 4 不写做 IIII,而是 IV。数字 1 在数字 5 的左边,所表示的数等于大数 5 减小数 1 得到的数值 4 。同样地,数字 9 表示为 IX。这个特殊的规则只适用于以下六种情况:

I 可以放在 V (5) 和 X (10) 的左边,来表示 4 和 9。
X 可以放在 L (50) 和 C (100) 的左边,来表示 40 和 90。
C 可以放在 D (500) 和 M (1000) 的左边,来表示 400 和 900。
给定一个整数,将其转为罗马数字。输入确保在 1 到 3999 的范围内。

思考:用的是分治法+暴力解题思想,将其拆分成一块一块的来进行分别表示。我得吐槽下,其实我最后想的也没有说明思想,就是按照罗马数字表达方式分别表达。而且这个题目,如果不懂罗马数字的完全做不出来呀!例如,300,200,700,800,2000等数字,如果不了解的话估计还得瞎猜!300=CCC,400=CD…

代码写的最简单,最快速,同时也是最安全的办法是写成多if,或者switch形式,空间,时间复杂度均为O(1),对人脑损害是∞。(ಡωಡ)

然后,稍微加点代码功底和思考的话,就是找到这里面的内在关系,然后采取字符集编码的方式,因为400,40其实就是使用了{C,D},{C,X}两个不同的字符集,这个感觉没暴力法简单。

13.罗马数字转整数

网址

题目:罗马数字包含以下七种字符: I, V, X, L,C,D 和 M。

字符 数值
I 1
V 5
X 10
L 50
C 100
D 500
M 1000
例如, 罗马数字 2 写做 II ,即为两个并列的 1。12 写做 XII ,即为 X + II 。 27 写做 XXVII, 即为 XX + V + II 。

通常情况下,罗马数字中小的数字在大的数字的右边。但也存在特例,例如 4 不写做 IIII,而是 IV。数字 1 在数字 5 的左边,所表示的数等于大数 5 减小数 1 得到的数值 4 。同样地,数字 9 表示为 IX。这个特殊的规则只适用于以下六种情况:

I 可以放在 V (5) 和 X (10) 的左边,来表示 4 和 9。
X 可以放在 L (50) 和 C (100) 的左边,来表示 40 和 90。
C 可以放在 D (500) 和 M (1000) 的左边,来表示 400 和 900。
给定一个罗马数字,将其转换成整数。输入确保在 1 到 3999 的范围内。

思考:这道题不就是将12题反过来考吗,穷举法可以完成这道题目,不过为了加快查找速度,会用到哈希表。下次一定写一个有关各种语言哈希表的构造,下次一定。。。。。

14. 最长公共前缀

网址

题目:编写一个函数来查找字符串数组中的最长公共前缀。

如果不存在公共前缀,返回空字符串 “”。

思考:看到这种题,我就会觉得C太痛苦了,换上痛苦面具,如果是python,可以直接用in,find来判断是否存在在这个数组当中。

我的思路是简单的来说,假设存在s1,s2,s3…sn这n个字符数组,那么先从f(s1,s2)找到二者之间的公共前缀,然后把公共前缀用一个空间进行存储,设为b1。然后再和s3进行对比,即b2=f(b1,s3),依次计算,直到bi是一个空数组或者便利完sn就结束。

我这个思路的空间复杂度为O(1),但时间复杂度过高,最糟糕的情况就是全部相同,所以公共前缀就是本身,这时的时间复杂度为O(mn),其中m是字符长度,n为字符数组数量。

貌似,也没用到python的in,find,好像也就是字符串的字符匹配。

15. 三数之和

网址

题目: 给你一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?请你找出所有和为 0 且不重复的三元组。

注意:答案中不可以包含重复的三元组。

这就是第一道题的翻版吗,二数之和就是神。看了下评论,大多是吐槽超时的。额,我是个纸上谈兵的人,先思考再动手吧,这道题我觉得完全按照二数之和的思路来写。

1.将数组nums进行排序,排序也不用写的太复杂,就算时间复杂度为O(n^2)。

2.建立HASH表,或者python中的字典,存储的数值为数组nums的负数。空间复杂度为O(n),时间复杂度为O(1)。

3.然后问题就变成了任取两位,看第三位是否在哈希表的问题,其时间复杂度为O(n^2)。

4.分析:简单的看第3步,任取两位是找第三位确实可行,虽然会出现重复问题,但可以通过除以3的方式来解决;另外一个问题是元素重复问题,虽然我很希望这是数学题中的集合,但显然这种想法过于天真,重复元素在集合当中是存在的情况,这就有可能出现{-3,-3,6}的情况。最后,就是取值顺序的选择,因为有些取值是毫无意义的,比如三个正数的相加或者三个负数的相加,但加判断感觉也太过于愚蠢。

5.优化:主要是对遍历方法的优化,一方面可以解决答案重复的问题,另一方面可以减少不必要的计算。我思考的遍历方法是,指针L,R开始分别指向左右两端,固定指针L,指针R向左移动。

当s[L]+s[R]能够在哈希表上找到时,停止移动,并记录此时三个数值;如果存在两数相等的情况,则再进行一次判断,判断数组中是否存在两个该字符。

当s[L]+S[R]的范围不在(-s[R],-S[L]),则直接break循环。因为我作的假设就是,第三值必须在两者之间,以保证结果的唯一性。

若S[R]存在相等的情况,只计算一次,下一次直接再指向下一个下标。

当下标L,R相等的时候,则停止循环,但显然在之前就已经停止了。

循环结束后,L前进一步,R复位到最右端,再进行新一轮循环。直到s[L]+S[R]的范围不在(-s[R],-S[L])时,终止外轮循环。

因为使用了两轮循环,其时间复杂度为O(n^2), 查找哈希表的时间为O(1),排序时间最快为O(nlogn),但这个没必要。因此最终时间复杂度为O(n^2)。

事后发现,这道题没必要使用hash,甚至可以说1.两数之和也没必要用hash,这里考察的都是对双指针的使用。

16. 最接近的三数之和

网址
有完没完呀,又是这种题目,呜呜呜!!!!

题目:给定一个包括 n 个整数的数组 nums 和 一个目标值 target。找出 nums 中的三个整数,使得它们的和与 target 最接近。返回这三个数的和。假定每组输入只存在唯一答案。

思考:这道题因为是算接近值,而不是确定值,想用hash查找是办不到的,只能老老实实的的来计算,如果暴力解决,则复杂度为O(n^3),这显然会超时的。

突然觉得前面的算式不需要用哈希了,使用hash还需要考虑各种问题。
首先,对数组进行排序,时间复杂度为O(nlogn)。

设置两个指针L和R,进行一个i从0-length-2的循环,L的初始值指向i+1,R的初始值指向最右端。

用sum来记录三值的大小,在这里sum=s[i]+s[L]+s[R],然后得到sum和target差值的绝对值。

如果这个差值绝对值小于原来的sum,则更新最接近三数。当sum值大于target时,则sum值为了减少要移动R左移;同理,小于时则时L右移。直到L=R时,这时移动n-i次。

接着按照这样的道理进行n-2次循环,最终获得最接近的三数。

这个算法的数学证明可以参照11.承最多的水,使用的是数学排除法的思想。

17. 电话号码的字母组合

网址
题目:给定一个仅包含数字 2-9 的字符串,返回所有它能表示的字母组合。答案可以按 任意顺序 返回。

给出数字到字母的映射如下(与电话按键相同)。注意 1 不对应任何字母。

在这里插入图片描述

思考:这题考察的是回溯法,题目是常考的题目,我下次一定要总结一下。因为时间复杂度是指数级,所以很容易超时。没时间,我还有其他事要做,以后再自己总结下该题吧。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

此人受打击,决定去力扣历练

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值