哈喽大家好,我是鹏哥。
最近一直没想好要写些什么主题,所以只好记录下最近刷到的一道Leetcode题吧 —— 456.132模式。
~~~上课铃~~~
1 写在前面
年后以来 ,我就经常想不好要写些什么东西,一方面自己python能力暂时没有提升,另一方面懒得写文章了(尽管已经是一周一篇,但是久了就怠了,没有初时的激情。)
最近在看徐子沛的《大数据》,书中有提到一位数据统计师(名字忘 了)百年前提出的数据统计方式在经过历史滚轮周而复始才最终得到认可。如果当时所做的事情或坚持的事情,在十年或百年后能值得他人的认可或者自己的敬佩,那也算有做下去的意义吧。
2 LeetCode 456题:132模式
【题目内容】:给定一个整数序列:a1, a2, ..., an,一个132模式的子序列 ai, aj, ak 被定义为:当 i < j < k 时,ai < ak < aj。设计一个算法,当给定有 n 个数字的序列时,验证这个序列中是否含有132模式的子序列。
链接如下:https://leetcode-cn.com/problems/132-pattern/
示例1:
输入: [1, 2, 3, 4]
输出: False
解释: 序列中不存在132模式的子序列。
示例 2:
输入: [3, 1, 4, 2]
输出: True
解释: 序列中有 1 个132模式的子序列:[1, 4, 2].
示例 3:
输入: [-1, 3, 2, 0]
输出: True
解释: 序列中有 3 个132模式的的子序列: [-1, 3, 2], [-1, 3, 0] 和 [-1, 2, 0].
3 解法示例
解法 1:暴力解
感觉平时写各种python小程序都能写得很快,但是一轮到这种考题就瞬间愣逼,只剩下暴力解了。有点像大学时的期末考试感觉。
class Solution(object):def find132pattern(self, nums):if len(nums) < 3:return Falsefor i in range(len(nums)):first = nums[i]for j in range(i + 1, len(nums)):if nums[j] > first:mid = nums[j]for k in range(j+1,len(nums)):if first < nums[k] < mid:return Truereturn False
解法 2:调用 itertools库
不得不说,python各类封装库对用户的友好。对于这个问题,直接调用 itertools库,只需要5行代码就能解决。
import itertoolsclass Solution(object):def find132pattern(self, nums):if len(nums) < 3:return Falseres = itertools.combinations(nums, 3)for i in res:if i[0] < i[2] < i[1]:return Truereturn False
combinations:用法是itertools.combinations(mylist,num),对mylist列表取出 任意num个元素进行组合; permutations:用法是itertools.combinations(mylist),对mylist列表所有元素进行排列
class Solution:def find132pattern(self, nums: List[int]) -> bool:stack = []for num in nums:if len(stack) == 0 or num < stack[-1][0]:stack.append([num, num])else:top_min = stack[-1][0]while len(stack) != 0 and num > stack[-1][1]:stack.pop()if len(stack) != 0 and num > stack[-1][0] and num < stack[-1][1]:return Truestack.append([top_min, num])return False
class Solution:def find132pattern(self, nums: List[int]) -> bool:stack=[]_Min=float("-inf")for i in range(len(nums)-1,-1,-1):if nums[i]<_Min:return Truewhile stack and nums[i]>stack[-1]:_Min=stack.pop()stack.append(nums[i])return False
132模式的解法大致就介绍到这里了,其中我最喜欢的是解法2和4,尽管2并不能满足运行时间要求,但是很pythonic。
4 那些惊艳的python代码
1、带索引、值的遍历(这个应该很常见)for i,k in enumerate(mylist)2、求列表排序后,之前的索引值列表[i for i,k in sorted(enumerate(mylist),reverse=True,key=lambda x:x[1])]3、求列表某值的索引位置[i for i,k in enumerate(mylist) if k == num]4、三元表达式return True if x>y else False5、将字符串大小写进行转换mystr.swapcase()6、将列表中的字符串按数字进行排序,如 ['b3','a10','c1']return sorted(mylist,key=lambda x:int(re.search('\d+').group(0)))7、对两个列表进行元素交接,使两列表的和差值最小list3 = list2 + list1list1 = min(itertools.combinations(list3,len(list1)),key=lambda x:abs(sum(x)-sum(list3)/2))8、求列表各元素的频度return {i:mylist.count(k) for i,k in enumerate(set(mylist))}
5 总结
~~~下课铃~~~
【往期热门文章】:
【Python成长之路】10行代码教你免费观看无广告版的《庆余年》腾讯视频
【关注“鹏哥贼优秀”公众号,回复“python学习材料”,将会有python基础学习、机器学习、数据挖掘、高级编程教程等100G视频资料,及100+份python相关电子书免费赠送!】
扫描二维码
与鹏哥一起
学python吧!