leetcode 11~20 学习经历
LeetCode 习题 11 - 20
- 11. 盛最多水的容器
- 12. 整数转罗马数字
- 13. 罗马数字转整数
- 14. 最长公共前缀
- 15. 三数之和
- 16. 最接近的三数之和
- 17. 电话号码的字母组合
- 18. 四数之和
- 19. 删除链表的倒数第 N 个结点
- 20. 有效的括号
- 小结
11. 盛最多水的容器
给定一个长度为 n 的整数数组 height 。有 n 条垂线,第 i 条线的两个端点是 (i, 0) 和 (i, height[i]) 。
找出其中的两条线,使得它们与 x 轴共同构成的容器可以容纳最多的水。
返回容器可以储存的最大水量。
说明:你不能倾斜容器。
示例 1:
输入:[1,8,6,2,5,4,8,3,7]
输出:49
解释:图中垂直线代表输入数组 [1,8,6,2,5,4,8,3,7]。在此情况下,容器能够容纳水(表示为蓝色部分)的最大值为 49。
示例 2:
输入:height = [1,1]
输出:1
提示:
n == height.length
2 <= n <= 10^5
0 <= height[i] <= 10^4
通过次数917,591提交次数1,513,670
来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/container-with-most-water
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
秀逗的脑袋不转圈,为什么第一想法都是暴力运算呢?
class Solution:def maxArea(self, height: List[int]) -> int:n = len(height)dp = [[0 for _ in range(n)] for _ in range(n)]for i in range(n):for j in range(i+1,n):dp[i][j] = min(height[i],height[j]) * (j - i)mx = [max(row) for row in dp]return max(mx)
这算法。。。按照用例范围10万数据。。。能过才见鬼了
也没多少用例数据嘛。。。才5屏半而已。。。。见鬼了。。。。
还是开始动动脑子吧。。。从两边往中间推,哪边的柱子低,哪边就往里推
class Solution:def maxArea(self, height: List[int]) -> int:mx = 0n = len(height)l = 0r = n - 1while True:c = min(height[l],height[r]) * (r - l)if c > mx:mx = cif height[l] > height[r]:r -= 1else:l += 1if l == r:breakreturn mx
额。。。居然通过了,我还说万一中间有几根高出天际的柱子,会影响计算,结果他没这情况
竟然。。。有不到50ms的成绩?赶紧学习!
一段时间过去了,程序看懂了,思路貌似也理解了,但绝对不会在以后能想起来。。。。。
这题基本都是双指针,和双指针优化了,到此为止,继续下一题。
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:
输入: num = 3
输出: “III”
示例 2:
输入: num = 4
输出: “IV”
示例 3:
输入: num = 9
输出: “IX”
示例 4:
输入: num = 58
输出: “LVIII”
解释: L = 50, V = 5, III = 3.
示例 5:
输入: num = 1994
输出: “MCMXCIV”
解释: M = 1000, CM = 900, XC = 90, IV = 4.
提示:
1 <= num <= 3999
通过次数362,078提交次数546,627
来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/integer-to-roman
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
这个题好像以前做过,很久以前很久以前。。。想不起来了!
算了,从新做一遍吧。
class Solution:def intToRoman(self, num: int) -> str:#num = 1994# MCMXCIVn = [1,5,10,50,100,500,1000]c = ['I','V','X','L','C','D','M']r = ''for i in range(7,0,-1):m = max((i // 2 - 1) * 2,0)v = n[i - 1]l = c[i - 1]#print(num,v)while num >= v:num -= vr += lif num > 0 and v - num <= n[m]:#print(v,num,n[m],r)r += c[m] + lnum -= v - n[m]#print(num,r)return r
额。。。。大佬这么多,看看分布,又是一群大佬集中?然后翻了翻头部的答案。。。。各种奇葩的节省时间思路啊。。。。真是无语了。。。
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:
输入: s = “III”
输出: 3
示例 2:
输入: s = “IV”
输出: 4
示例 3:
输入: s = “IX”
输出: 9
示例 4:
输入: s = “LVIII”
输出: 58
解释: L = 50, V= 5, III = 3.
示例 5:
输入: s = “MCMXCIV”
输出: 1994
解释: M = 1000, CM = 900, XC = 90, IV = 4.
提示:
1 <= s.length <= 15
s 仅含字符 (‘I’, ‘V’, ‘X’, ‘L’, ‘C’, ‘D’, ‘M’)
题目数据保证 s 是一个有效的罗马数字,且表示整数在范围 [1, 3999] 内
题目所给测试用例皆符合罗马数字书写规则,不会出现跨位等情况。
IL 和 IM 这样的例子并不符合题目要求,49 应该写作 XLIX,999 应该写作 CMXCIX 。
关于罗马数字的详尽书写规则,可以参考 罗马数字 - Mathematics 。
通过次数776,067提交次数1,245,617
来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/roman-to-integer
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
这一题就是上一题的逆运算,说实话,这个比上一个还简单,碰到前边数字小于后边数字的,就减去前边数字就好,其他都是加法,这个题,也不想拼什么执行时间了,没啥感觉
class Solution:def romanToInt(self, s: str) -> int:n = [1,5,10,50,100,500,1000]l = ['I','V','X','L','C','D','M']r = 0for i in range(len(s)):if i < len(s) - 1:if l.index(s[i]) >= l.index(s[i + 1]):r += n[l.index(s[i])]else:r -= n[l.index(s[i])]else:r+= n[l.index(s[i])]return r
14. 最长公共前缀
编写一个函数来查找字符串数组中的最长公共前缀。
如果不存在公共前缀,返回空字符串 “”。
示例 1:
输入:strs = [“flower”,“flow”,“flight”]
输出:“fl”
示例 2:
输入:strs = [“dog”,“racecar”,“car”]
输出:“”
解释:输入不存在公共前缀。
提示:
1 <= strs.length <= 200
0 <= strs[i].length <= 200
strs[i] 仅由小写英文字母组成
通过次数1,027,298提交次数2,377,782
来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/longest-common-prefix
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
这一题也很简单,暴力莽过去看看
class Solution:def longestCommonPrefix(self, strs: List[str]) -> str:r = ''n = min([len(n) for n in strs])for i in range(n):if ''.join([n[i] for n in strs]) != strs[0][i] * len(strs):breakr += strs[0][i]return r
额。。。虽然在预计内,但还是没想到大家应该都是暴力莽的
15. 三数之和
给你一个整数数组 nums ,判断是否存在三元组 [nums[i], nums[j], nums[k]] 满足 i != j、i != k 且 j != k ,同时还满足 nums[i] + nums[j] + nums[k] == 0 。请
你返回所有和为 0 且不重复的三元组。
注意:答案中不可以包含重复的三元组。
示例 1:
输入:nums = [-1,0,1,2,-1,-4]
输出:[[-1,-1,2],[-1,0,1]]
解释:
nums[0] + nums[1] + nums[2] = (-1) + 0 + 1 = 0 。
nums[1] + nums[2] + nums[4] = 0 + 1 + (-1) = 0 。
nums[0] + nums[3] + nums[4] = (-1) + 2 + (-1) = 0 。
不同的三元组是 [-1,0,1] 和 [-1,-1,2] 。
注意,输出的顺序和三元组的顺序并不重要。
示例 2:
输入:nums = [0,1,1]
输出:[]
解释:唯一可能的三元组和不为 0 。
示例 3:
输入:nums = [0,0,0]
输出:[[0,0,0]]
解释:唯一可能的三元组和为 0 。
提示:
3 <= nums.length <= 3000
-10^5 <= nums[i] <= 10^5
通过次数1,264,583提交次数3,442,609
来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/3sum
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
暴力,我们崇尚暴力!虽然知道肯定过不去,但还是要发泄一下暴力!
class Solution:def threeSum(self, nums: List[int]) -> List[List[int]]:#nums = [-1,0,1,2,-1,-4,-2,-3,3,0,4]result = []nums.sort()n = len(nums)p = 0while p < n:t = nums[p]if t > 0:breakfor i in range(p + 1,n - 1):if (t + nums[i]) * -1 in nums[i + 1:]:c = [t,nums[i],(t + nums[i]) * -1]c.sort()if not c in result:result.append(c)p += 1result.sort()return result
一时半会的,也不知道怎么优化,折腾了半天还是超时,先换个思路看看
class Solution:def threeSum(self, nums: List[int]) -> List[List[int]]:result = []if len(nums)==3 and sum(nums)==0:result.append(nums)return resulta,b,c=[n for n in nums if n<0],[n for n in nums if n==0],[n for n in nums if n>0]a.sort()c.sort()sa = set(a)sc = set(c)if len(b)>2:result.append([0,0,0])if len(b) > 0:for i in a:if abs(i) in c and [i,0,abs(i)] not in result:result.append([i,0,abs(i)])if len(a) == 0 or len(c) == 0:return resultif len(a)>1:mx = c[-1]n = len(a)for i in range(n - 1):for j in range(n - 1,i,-1):v = abs(a[i] + a[j])if v > mx:breakif v in sc and not [a[i],a[j],v] in result:result.append([a[i],a[j],v])if len(c)>1:mx = abs(a[0])n = len(c)for j in range(n - 1,0,-1):for i in range(j):v = c[i] + c[j]if v > mx:breakif v * -1 in sa and not [v * -1,c[i],c[j]] in result:result.append([v * -1,c[i],c[j]])result.sort()return result
好歹是通过了。。。这个就是把负数放一起,正数放一起,分开算,负数和取绝对值在正数里找对应,反之亦然
但很明显,这个算法也很土了,更不要说成绩了,总算自己完成一版,然后开始去看官方题解
抄了一遍官方题解,效率也就比我的好一些,但成绩还是排不上号啊
class Solution:def threeSum(self, nums: List[int]) -> List[List[int]]:n = len(nums)nums.sort()ans = list()# 枚举 afor first in range(n):# 需要和上一次枚举的数不相同if first > 0 and nums[first] == nums[first - 1]:continue# c 对应的指针初始指向数组的最右端third = n - 1target = -nums[first]# 枚举 bfor second in range(first + 1, n):# 需要和上一次枚举的数不相同if second > first + 1 and nums[second] == nums[second - 1]:continue# 需要保证 b 的指针在 c 的指针的左侧while second < third and nums[second] + nums[third] > target:third -= 1# 如果指针重合,随着 b 后续的增加# 就不会有满足 a+b+c=0 并且 b<c 的 c 了,可以退出循环if second == third:breakif nums[second] + nums[third] == target:ans.append([nums[first], nums[second], nums[third]])return ans作者:LeetCode-Solution
链接:https://leetcode.cn/problems/3sum/solution/san-shu-zhi-he-by-leetcode-solution/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
然后,我就想不明白了,为什么我的代码就超时呢?下边代码和上边代码区别很大吗?
class Solution:def threeSum(self, nums: List[int]) -> List[List[int]]:result = []nums.sort()n = len(nums)for i in range(n):if nums[i] > 0:breakif i > 0 and nums[i] == nums[i - 1]:continuet = abs(nums[i])for j in range(i+1,n):if j > i + 1 and nums[j] == nums[j - 1]:continuefor k in range(n - 1,j,-1):if k < n - 1 and nums[k] == nums[k + 1]:continueif nums[k] + nums[j] > t:continueif nums[k] < 0:breakif nums[i] + nums[j] + nums[k] == 0:result.append([nums[i],nums[j],nums[k]])if nums[i] + nums[j] + nums[k] < 0:breakreturn result
最后,还是按照题解的完整的抄了一遍,注意 k 赋值的位置
class Solution:def threeSum(self, nums: List[int]) -> List[List[int]]:result = []nums.sort()n = len(nums)for i in range(n - 2):if i > 0 and nums[i] == nums[i - 1]:continuet = -nums[i]k = n - 1for j in range(i+1,n):if j > i + 1 and nums[j] == nums[j - 1]:continuef = nums[j]while j < k and f + nums[k] > t:k -= 1if j == k:breakif f + nums[k] == t:#if [nums[i],nums[j],nums[k]] not in result:result.append([nums[i],nums[j],nums[k]])return result
class Solution:def threeSum(self, nums: List[int]) -> List[List[int]]:result = []nums.sort()n = len(nums)for i in range(n - 2):if i > 0 and nums[i] == nums[i - 1]:continuet = -nums[i]for j in range(i+1,n):if j > i + 1 and nums[j] == nums[j - 1]:continuef = nums[j]k = n - 1 # k赋值放到2层循环里,超时while j < k and f + nums[k] > t:k -= 1if j == k:breakif f + nums[k] == t:#if [nums[i],nums[j],nums[k]] not in result:result.append([nums[i],nums[j],nums[k]])return result
那么,里面第三层循环用 for 那就更没跑的超时了。。。这题真难,比第10题正则的都难。。。55555
还有好多高分答案没看呢,继续学习吧。。。。bisect 是啥?头部答案基本都用了这个。。。。也没有 import 看一下,纳闷了
然后,结合字典和我自己搞出的5000ms的思路,从新优化出一版
class Solution:def threeSum(self, nums: List[int]) -> List[List[int]]:result = []d = Counter(nums)l = sorted(d)for x in range(len(l)):i = l[x]if i == 0 and d[i] > 2:result.append([0,0,0])if d[i] > 1 and (i * -2) in d and i != 0:result.append([i,i,i * -2])if i < 0 and -i in d and d[0] > 0:result.append([i,0,-i])if i < 0:for y in range(x + 1,len(l)):j = l[y]if j == 0:continuet = (i + j) * -1if t in d and t != 0:if i < t and j < t:result.append([i,j,t])return result
除了头部的那个看不懂的 bisect ,其他的考前的都是双指针操作,我就不尝试了,思路学会了就继续下一题
16. 最接近的三数之和
给你一个长度为 n 的整数数组 nums 和 一个目标值 target。请你从 nums 中选出三个整数,使它们的和与 target 最接近。
返回这三个数的和。
假定每组输入只存在恰好一个解。
示例 1:
输入:nums = [-1,2,1,-4], target = 1
输出:2
解释:与 target 最接近的和是 2 (-1 + 2 + 1 = 2) 。
示例 2:
输入:nums = [0,0,0], target = 1
输出:0
提示:
3 <= nums.length <= 1000
-1000 <= nums[i] <= 1000
-10^4 <= target <= 10^4
通过次数441,101提交次数976,526
来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/3sum-closest
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
这个题。。。。。和前边的三数和的思路一样啊,唯一不同的就是有一个不确定的 target,而且这个 target 很飘逸,很有可能是比三个最大正数和还打上不少,或者比三个负数和小上不少,这里就出现了一个小问题,怎么确认一个初始的 target 来记录当前最接近 target 的三数和呢?好在提示里有,target 的范围,那就弄出一个超出这个范围的数最为起始值好了
class Solution:def threeSumClosest(self, nums: List[int], target: int) -> int:#nums = [4,0,5,-5,3,3,0,-4,-5]#target = -2nums.sort()n = len(nums)if n < 3:return Nonemn = 1e5for i in range(n):if i > 0 and nums[i] == nums[i - 1]:continuel,r = i + 1,n - 1while l < r:while l < r and l > i + 1 and nums[l] == nums[l - 1]:l += 1while r> l and r < n - 1 and nums[r] == nums[r + 1]:r -= 1if l >= r:breakc = nums[i] + nums[l] + nums[r]#print(n,i,l,r,'n:',nums[i],nums[l],nums[r],c)if abs(c - target) < abs(mn - target):mn = cif mn == target:break#if abs(nums[l] - target) < abs(nums[r] - target):if c < target:l += 1else:r -= 1return mn
额,提交的时候,有几个用例错误了,就是双指针,是根据什么移动左还是右的问题
这个成绩一看就是基础不稳,之前的三数和没做好,这个题就很难做好了,从新学习这两题的大佬的答案吧,然后,还是一堆看不懂的东西。。。不过,有个思路倒是很合适,在开始循环前判断前三后三的和与target比较,然后稍微调整了一下,执行时间就。。。。哎。。。用例的问题
class Solution:def threeSumClosest(self, nums: List[int], target: int) -> int:#nums = [4,0,5,-5,3,3,0,-4,-5]#target = -2nums.sort()n = len(nums)if n < 3:return Noneif sum(nums[:3]) >= target:return sum(nums[:3])if sum(nums[-3:]) <= target:return sum(nums[-3:])mn = 1e5for i in range(n):if mn == target:breakif i > 0 and nums[i] == nums[i - 1]:continuel,r = i + 1,n - 1while l < r:while l < r and l > i + 1 and nums[l] == nums[l - 1]:l += 1while r> l and r < n - 1 and nums[r] == nums[r + 1]:r -= 1if l >= r:breakc = nums[i] + nums[l] + nums[r]if abs(c - target) < abs(mn - target):mn = cif mn == target:breakif c < target:l += 1else:r -= 1return mn
既然知道用例有问题,那么久再调整一下
class Solution:def threeSumClosest(self, nums: List[int], target: int) -> int:#nums = [4,0,5,-5,3,3,0,-4,-5]#target = -2nums.sort()n = len(nums)if n < 3:return Noneif sum(nums[:3]) >= target:return sum(nums[:3])if sum(nums[-3:]) <= target:return sum(nums[-3:])mn = 1e5for i in range(n - 2):if mn == target:breakif i > 0 and nums[i] == nums[i - 1]:continueif nums[i] + nums[-1] + nums[-2] < target:continuel,r = i + 1,n - 1while l < r:while l < r and l > i + 1 and nums[l] == nums[l - 1]:l += 1while r> l and r < n - 1 and nums[r] == nums[r + 1]:r -= 1if l >= r:breakc = nums[i] + nums[l] + nums[r]if abs(c - target) < abs(mn - target):mn = cif mn == target:breakif c < target:l += 1else:r -= 1return mn
https://leetcode.cn/submissions/detail/404423668/
竟然还有这评价?无敌了。。。。
17. 电话号码的字母组合
给定一个仅包含数字 2-9 的字符串,返回所有它能表示的字母组合。答案可以按 任意顺序 返回。
给出数字到字母的映射如下(与电话按键相同)。注意 1 不对应任何字母。
示例 1:
输入:digits = “23”
输出:[“ad”,“ae”,“af”,“bd”,“be”,“bf”,“cd”,“ce”,“cf”]
示例 2:
输入:digits = “”
输出:[]
示例 3:
输入:digits = “2”
输出:[“a”,“b”,“c”]
提示:
0 <= digits.length <= 4
digits[i] 是范围 [‘2’, ‘9’] 的一个数字。
通过次数637,332提交次数1,097,933
来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/letter-combinations-of-a-phone-number
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
这个题目其实很简单,主要就是读题,刚开始,老顾一下子挺蒙的,为什么23会出来这么多字母,后来才想明白,这不就是9键手机键盘的对应字母么,然后求最大组合
class Solution:def letterCombinations(self, digits: str) -> List[str]:d = {2:'abc',3:'def',4:'ghi',5:'jkl',6:'mno',7:'pqrs',8:'tuv',9:'wxyz'}r = self.makeGroup(digits,d) if len(digits)>0 else []return rdef makeGroup(self,s,d):r = []l = int(s[0])s = s[1:]z = d[l]if len(s) == 0:return list(z)for n in z:r += [n+x for x in self.makeGroup(s,d)]return r
这题没什么说的,递归一下什么都有了,而且范围也小
18. 四数之和
给你一个由 n 个整数组成的数组 nums ,和一个目标值 target 。请你找出并返回满足下述全部条件且不重复的四元组 [nums[a], nums[b], nums[c], nums[d]] (若两个四元组元素一一对应,则认为两个四元组重复):
0 <= a, b, c, d < n
a、b、c 和 d 互不相同
nums[a] + nums[b] + nums[c] + nums[d] == target
你可以按 任意顺序 返回答案 。
示例 1:
输入:nums = [1,0,-1,0,-2,2], target = 0
输出:[[-2,-1,1,2],[-2,0,0,2],[-1,0,0,1]]
示例 2:
输入:nums = [2,2,2,2,2], target = 8
输出:[[2,2,2,2]]
提示:
1 <= nums.length <= 200
-10^9 <= nums[i] <= 10^9
-10^9 <= target <= 10^9
通过次数417,575提交次数1,114,508
来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/4sum
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
额。。。。本次刷题最难的应该是这个吧?看了看提示,只有200个数,那么暴力应该能通过吧?
那就暴力来一次看看
class Solution:def fourSum(self, nums: List[int], target: int) -> List[List[int]]:nums.sort()r = self.makeGroup(nums,target,[],4)return rdef makeGroup(self,arr,t,r,x):if x == 1:result = []d = set(arr)if t in d:result.append(r + [t])return resultreturn resultresult = []for i in range(len(arr) - x + 1):if i > 0 and arr[i] == arr[i - 1]:continueresult += self.makeGroup(arr[i + 1:],t - arr[i],r + [arr[i]],x - 1)return result
啧啧,还真通过了,那就继续翻动一下咸鱼的脑干,答题思路不变,还是递归,稍微调整下跳出
class Solution:def fourSum(self, nums: List[int], target: int) -> List[List[int]]:nums.sort()r = self.makeGroup(nums,target,[],4)return rdef makeGroup(self,arr,t,r,x):if x == 1:if arr.count(t) > 0:return [r + [t]]return []result = []v = sum(arr[-x + 1:])for i in range(len(arr) - x + 1):if i > 0 and arr[i] == arr[i - 1]:continueif t- arr[i] > v:continueresult += self.makeGroup(arr[i + 1:],t - arr[i],r + [arr[i]],x - 1)return result
啧啧,用时少了一半,成绩还是这个档次,暂时用递归不知道怎么优化了,开始抄作业。官方题解真没啥作用。然后看了下答案分布。。。啧啧,名落孙山了
看了看大家的答案,貌似都是双循环双指针,感觉以后还有5数和,不定数量的数之和之类的,难道没有一个通用的高效办法吗?这个问题先记下了,以后学明白了,单独针对这个问题写个学习经历。
最后调整一下,在递归里最后两层循环改成双指针
class Solution:def fourSum(self, nums: List[int], target: int) -> List[List[int]]:nums.sort()self.r = []self.makeGroup(nums,target,[],4)return self.rdef makeGroup(self,arr,t,r,x):if x == 2:m,n = 0,len(arr) - 1while m < n:while m > 0 and m < n and arr[m] == arr[m - 1]:m += 1while n > m and n < len(arr) - 1 and arr[n] == arr[n + 1]:n -= 1if m == n:breakif arr[m] + arr[n] > t:n -= 1elif arr[m] + arr[n] < t:m += 1else:self.r.append(r + [arr[m],arr[n]])m += 1n -= 1returnv = sum(arr[-x + 1:])for i in range(len(arr) - x + 1):if i > 0 and arr[i] == arr[i - 1]:continueif t- arr[i] > v:continueself.makeGroup(arr[i + 1:],t - arr[i],r + [arr[i]],x - 1)
这成绩暂时能接受了,以后学有所得的时候再继续优化
19. 删除链表的倒数第 N 个结点
给你一个链表,删除链表的倒数第 n 个结点,并且返回链表的头结点。
示例 1:
输入:head = [1,2,3,4,5], n = 2
输出:[1,2,3,5]
示例 2:
输入:head = [1], n = 1
输出:[]
示例 3:
输入:head = [1,2], n = 1
输出:[1]
提示:
链表中结点的数目为 sz
1 <= sz <= 30
0 <= Node.val <= 100
1 <= n <= sz
进阶:你能尝试使用一趟扫描实现吗?
通过次数1,037,729提交次数2,295,516
来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/remove-nth-node-from-end-of-list
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
老顾对链表完全不了解啊,什么叫只扫描一趟?还是先做出来再考虑吧
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, val=0, next=None):
# self.val = val
# self.next = next
class Solution:def removeNthFromEnd(self, head: Optional[ListNode], n: int) -> Optional[ListNode]:arr = []while head:arr.append(head.val)head = head.nextarr.pop(-n)if len(arr) > 0:head = ListNode()r = headfor i in range(len(arr)):head.val = arr[i]if i < len(arr) - 1:head.next = ListNode()head = head.nextreturn rreturn None
这个办法肯定是不对的,他重构了一趟链表,看了看官方题解,三种方法大概理解了一点点,只是双指针方式自己没尝试成功,还是对链表不熟悉的过,以后补课
20. 有效的括号
给定一个只包括 ‘(’,‘)’,‘{’,‘}’,‘[’,‘]’ 的字符串 s ,判断字符串是否有效。
有效字符串需满足:
左括号必须用相同类型的右括号闭合。
左括号必须以正确的顺序闭合。
每个右括号都有一个对应的相同类型的左括号。
示例 1:
输入:s = “()”
输出:true
示例 2:
输入:s = “()[]{}”
输出:true
示例 3:
输入:s = “(]”
输出:false
提示:
1 <= s.length <= 10^4
s 仅由括号 ‘()[]{}’ 组成
通过次数1,377,119提交次数3,105,792
来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/valid-parentheses
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
这个。。。送分题,考队列的,弄个队列对上开始结束就ok
class Solution:def isValid(self, s: str) -> bool:d = len(s)if d == 0:return Trueif d % 2 == 1:return Falsed = {']':'[','}':'{',')':'('}l = ''for i in s:if len(l) == 0:if i in d:return Falseelse:l += ielif i in '[{(':l += ielif l[-1] != d[i]:return Falseelse:l = l[:-1]if len(l) > 0:return Falsereturn True
小结
三数和,四数和,不定数量数的和。。。真难啊,以后还要努力学习,除了这三个数和问题,其他问题相对简单,大家一起加油吧
相关文章:

leetcode 11~20 学习经历
LeetCode 习题 11 - 2011. 盛最多水的容器12. 整数转罗马数字13. 罗马数字转整数14. 最长公共前缀15. 三数之和16. 最接近的三数之和17. 电话号码的字母组合18. 四数之和19. 删除链表的倒数第 N 个结点20. 有效的括号小结11. 盛最多水的容器 给定一个长度为 n 的整数数组 heigh…...

LeetCode 双周赛 98,脑筋急转弯转不过来!
本文已收录到 AndroidFamily,技术和职场问题,请关注公众号 [彭旭锐] 提问。 大家好,我是小彭。 昨晚是 LeetCode 第 98 场双周赛,你参加了吗?这场周赛需要脑筋急转弯,转不过来 Medium 就会变成 Hard&#…...

函数的栈帧的创建和销毁
文章目录本章主题:一.什么是函数栈帧1.什么是栈2.什么是函数栈帧二.理解函数栈帧能解决什么问题呢?三.函数栈帧的创建和销毁解析1.预备知识(1) 认识相关寄存器和汇编指令(2)栈帧空间的维护2.解析函数栈帧的…...
python filtermapreducezip
一、filter 过滤 filter 过滤, 从可迭代对象中,筛选出满足条件的元素,再将这些满足条件的元素,组成一个新的可迭代对象。 方式一:filter(过滤方法,可迭代对象) 举例:将一个list中…...

Centos7搭建hadoop3.3.4分布式集群
文章目录1、背景2、集群规划2.1 hdfs集群规划2.2 yarn集群规划3、集群搭建步骤3.1 安装JDK3.2 修改主机名和host映射3.3 配置时间同步3.4 关闭防火墙3.5 配置ssh免密登录3.5.1 新建hadoop部署用户3.5.2 配置hadoopdeploy用户到任意一台机器都免密登录3.7 配置hadoop3.7.1 创建目…...

骨传导耳机工作原理,骨传导耳机优缺点
骨传导耳机虽说最近是十分火爆的一款单品,但还是有很多人对骨传导耳机不是很了解,骨传导耳机更多使用场景还是在户外运动使用,骨传导耳机对于长时间使用耳机的人来说十分友好,这主要还是得益于骨传导耳机传输声音的特殊性。 下面我…...

IDEA高效插件和设置
安装好Intellij idea之后,进行如下的初始化操作,工作效率提升十倍。 一. 安装插件 1. Codota 代码智能提示插件 只要打出首字母就能联想出一整条语句,这也太智能了,还显示了每条语句使用频率。 原因是它学习了我的项目代码&…...

Linux之网络流量监控工具ntopng YUM安装
一、ntopng简介 Ntop是一种监控网络流量工具,用ntop显示网络的使用情况比其他一些网络管理软件更加直观、详细。Ntop甚至可以列出每个节点计算机的网络带宽利用率。他是一个灵活的、功能齐全的,用来监控和解决局域网问题的工具;尤其当ntop与n…...

创建虚拟机,安装CentOS
在VMware上面创建虚拟机 文件->新建虚拟机 选定 自定义的高级,下一步 下一步 检查选定稍后安装操作系统 下一步 选择Linux,CentOS 7 64位 创建虚拟机名称,以及在存放该虚拟机的位置 选择处理器的数量和每个处理器的内核数量 …...

ilasm 和 ildasm编译和反编译工具介绍使用教程
目录前言一、使用 ildasm 反编译 dll 文件二、使用 ilasm 将il文件编译成 dll 或 exe 文件前言 文本讲述怎么通过 ildasm 工具将 dll 文件进行反编译为 il 文件,修改 il 文件后再如何通过 ilasm 工具将 il 文件反编译成 dll 或 exe 文件。 ildasm工具:…...

代码随想录【Day20】| 654. 最大二叉树、617. 合并二叉树、700. 二叉搜索树中的搜索、98. 验证二叉搜索树
654. 最大二叉树 题目链接 题目描述: 给定一个不含重复元素的整数数组。一个以此数组构建的最大二叉树定义如下: 二叉树的根是数组中的最大元素。 左子树是通过数组中最大值左边部分构造出的最大二叉树。 右子树是通过数组中最大值右边部分构造出的最…...

C++空指针和野指针
空指针:指针被赋值为空 例如: int* p nullptr;int* p NULL; 空指针指向的地址是00000000,但空指针不可以解引用 野指针:指针指向了不可控的位置 例如: 未初始化 int* p; //野指针 越界访问 int intArr[5]{0, 1, …...

LinkedList正确的遍历方式-附源码分析
1.引子 记得之前面试过一个同学,有这么一个题目: LinkedList<String> list new LinkedList<>();for (int i 0; i < 1000; i) {list.add(i "");}请根据上面的代码,请选择比较恰当的方式遍历这个集合,并…...

【蓦然回首忆Java·基础卷Ⅱ】
文章目录对象内存解析方法的参数传递机制关键字:package、importpackage(包)JDK中主要的包介绍import(导入)JavaBeanUML类图继承的一些细节封装性中的4种权限修饰关键字:supersuper的理解super的使用场景子类中调用父类被重写的方法子类中调用父类中同名…...

Mybatis源码分析系列之第二篇:Mybatis的数据存储对象
前言:SQLSession是对JDBC的封装 一:SQLSession和JDBC的对照说明 左边是我们的客户端程序,右边是我们的MySQL数据仓,或者叫MySQL实例 Mybatis是对JDBC的封装,将JDBC封装成了一个核心的SQLSession对象 JDBC当中的核心对…...

防护设备检测实验室建设完整方案SICOLAB
防护设备检测实验室建造布局方案SICOLAB一、防护设备检测实验室通常需要划分为几个功能区域,包括:1、样品准备区:用于样品的接收、处理、准备等工作,通常包括样品接收台、洗手池、样品切割机等设备。2、实验操作区:用于…...

Linux知识之主机状态
1、查看系统资源占用 •可以通过top命令查看CPU、内存使用情况,类似Windows的任务管理器默认每5秒刷新一次,语法:直接输入top即可,按q或ctrl c退出 2、 top命令内容详解 •第一行:top:命令名称࿰…...

是时候为您的银行机构选择构建一个知识库了!
知识管理和自助服务客户支持在银行业至关重要。选择正确的知识库对于帮助客户和在内部共享信息同样重要。繁重的法规和合规性需求意味着银行必须在他们选择的知识库类型上投入大量思考。许多银行知识库已经过时,无法为客户提供成功使用您的产品和服务所需的信息。在…...

「TCG 规范解读」第7章 TPM工作组 TPM 总结
可信计算组织(Ttrusted Computing Group,TCG)是一个非盈利的工业标准组织,它的宗旨是加强在相异计算机平台上的计算环境的安全性。TCG于2003年春成立,并采纳了由可信计算平台联盟(the Trusted Computing Platform Alli…...
一、Plugin Constructing the Boilerplate
构建样板文件 在本章中,你将学习如何为一个新插件构建最少的代码。从起点开始,您将看到如何获取GStreamer模板源代码。然后,您将学习如何使用一些基本工具来复制和修改模板插件,以创建一个新的插件。如果您遵循这里的示例&#x…...

高频面试--redis
Reids 1. 常见的数据结构(string, list, hash, set, zset) 答法模板: Redis 提供五种核心数据结构: String:最基本的类型,支持整数、自增、自减、位操作。 List:双端链表,支持消息…...
CSS--background-repeat详解
属性介绍 background-repeat 属性在CSS中用于控制背景图像是否以及如何重复。当背景图像的尺寸小于其容器的尺寸时,该属性决定了图像如何填充额外的空间。默认情况下,背景图像会在横向和纵向上重复,直到覆盖整个元素。 常见取值 repeat …...
leetcode450.删除二叉搜索树中的节点:迭代法巧用中间节点应对多场景删除
一、题目深度解析与BST特性剖析 在二叉搜索树(BST)中删除节点,需确保删除操作后树依然保持BST特性。题目要求我们根据给定的节点值key,在BST中删除对应节点。BST的核心特性是左子树所有节点值小于根节点值,右子树所有…...

Linux线程入门
目录 Linux线程概念 什么是线程 重新理解进程 线程的优点 线程的缺点 线程的异常 线程用途 Linux线程概念 什么是线程 在一个程序里的一个执行路线就叫做线程(thread)。更准确的定义是:线程是“一个进程内部的控制序列”。一切进程至…...

文档处理的相关工具
目前网页端的文档,可以通过沉浸式翻译来进行翻译阅读和学习。 但是某些文献只有pdf下载的版本,所以需要一个免费的针对pdf的翻译工具。 保留公式和图片格式。 推荐一个pdf翻译的工具,可以自己部署使用。如果需要word版本,后面讨论…...
高级特性实战:死信队列、延迟队列与优先级队列(二)
三、延迟队列:实现任务定时执行 3.1 延迟队列概念解析 延迟队列(Delay Queue),是一种特殊的队列,它的独特之处在于队列中的元素(消息)并不会立即被处理,而是会在指定的延迟时间过后…...
小表驱动大表更快吗,不是
背景 head头表(5000),line行表(15万),导出数据包含头和行,一对多。 以行表为维度导出15万数据。 sql 如下两个sql查询,有如下差异 驱动方式:第一个大表驱动小表&…...
Kotlin 活动事件通讯跳转深度讲解
在 Android 开发的浩瀚海洋中,活动(Activity)间的事件通讯与跳转犹如构建复杂应用程序的桥梁与纽带,而 Kotlin 语言的加入,更是为这一过程注入了简洁、优雅与高效的活力。本文将深入剖析 Kotlin 开发中安卓活动事件通讯跳转的方方面面,从基础概念到高级技巧,从代码示例到…...
C++双线程交替打印奇偶数(活泼版)
C双线程交替打印奇偶数(活泼版) 文章目录 C双线程交替打印奇偶数(活泼版)1.🎮 游戏规则说明书2.🔧 游戏道具准备区2.1🧩 道具清单 3.👯♂️ 创建两个线程小伙伴3.1🧑…...

【密码学——基础理论与应用】李子臣编著 第十三章 数字签名 课后习题
题目 逐题解析 13.1 知道p83,q41,h2,g4,x57,y77。 我看到答案,“消息M56”的意思居然是杂凑值,也就是传统公式的H(M)。 选择k23,那么r(g^k mod p) mod q 51 mod 4110,sk(H(M)xr) mod q29 ws mod q17,u1(mw) mod q9,u2(rw) m…...