2021-08-09leetcode刷题

近几天使用的进阶python语法

  • zip(*)将列转换为行,是二维数组转换为[(),(),()]形式。
  • set()增加元素使用add
  • 列表由值找索引,使用index(value)
  • 二分查找,bisect类有bisect_left和bisect_right函数(object,target),返回的是idx
  • python3的duque队列模块是双向队列,其中append和pop均在右侧进行,appendleft和popleft()在左侧进行。

对于连续子序列的和问题,可以考虑前缀和+哈希优化(对于哈希的查找是O(1),而非O(N))

重点:使用哈希前将h[i]-h[j-1]==k转换为h[j-1]==h[i]-k即查找h[i]-k出现的次数,即相当于查找了h[j-1],其个数即哈希值

给定一个整数数组和一个整数 k,你需要找到该数组中和为 k 的连续的子数组的个数。
示例 1 :
输入:nums = [1,1,1], k = 2
输出: 2 , [1,1] 与 [1,1] 为两种不同的情况。

class Solution:
    def subarraySum(self, nums: List[int], k: int) -> int:
        pre=0
        dict_={0:1}
        ans=0
        for i in nums:
            pre+=i
            ans+=dict_.get(pre-k,0)
            dict_[pre]=dict_.get(pre,0)+1
        print(dict_)
        return ans
            


        '''
        #前后指针
        left,right=0,0
        ans=0
        cnt=0
        while right<len(nums):
            if cnt+nums[right]<k:
                cnt+=nums[right]
                right+=1
            elif cnt+nums[right]==k:
                cnt+=nums[right]
                ans+=1
                cnt-=nums[left]
                left+=1
                right+=1
            else:
                cnt-=nums[left]
                if left==right:
                    right+=1
                left+=1
        return ans
        '''
                
            

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/subarray-sum-equals-k
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

image.png

自我感觉使用了O(1)的内存和O(N)的时间复杂度

给你一个整数数组 nums ,判断这个数组中是否存在长度为 3 的递增子序列。
如果存在这样的三元组下标 (i, j, k) 且满足 i < j < k ,使得 nums[i] < nums[j] < nums[k] ,返回 true ;否则,返回 false 。
输入:nums = [1,2,3,4,5]
输出:true
解释:任何 i < j < k 的三元组都满足题意

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/increasing-triplet-subsequence
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

class Solution:
    def increasingTriplet(self, nums: List[int]) -> bool:
        if len(nums)<3:
            return False
        #last_min_left,last_min_right,min_left,min_right=0,0,0,0
        flag=False#记录有没有找到right
        min_left,min_right=nums[0],nums[1]
        if min_right>min_left:
            flag=True
        elif min_right<min_left:
            min_left,min_right=min_right,min_left
        for i in nums[2:]:
            #print(min_left,min_right,flag)
            if min_left>i:
                min_left=i
            elif i>min_left and not flag:
                min_right=i
                flag=True
            elif flag and min_left<i<min_right:
                min_right=i
            elif flag and i>min_right:
                return True
            
        return False
        
            
image.png

注意在python中set是哈希表

字符串 S 由小写字母组成。我们要把这个字符串划分为尽可能多的片段,同一字母最多出现在一个片段中。返回一个表示每个字符串片段的长度的列表。
示例:
输入:S = "ababcbacadefegdehijhklij"
输出:[9,7,8]
解释:
划分结果为 "ababcbaca", "defegde", "hijhklij"。
每个字母最多出现在一个片段中。
像 "ababcbacadefegde", "hijhklij" 的划分是错误的,因为划分的片段数较少。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/partition-labels
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

class Solution:
    def partitionLabels(self, s: str) -> List[int]:
        #O(N^2)的复杂度不知道能不能过
        hash_set=set()
        def first_end_idx(c:str,s):
            #st,ed=-1,len(s)
            st=s.find(c)
            ed=len(s)-s[::-1].find(c)-1
            '''
            if c=='a':
                print(st,ed)
            '''
            return st,ed
        ans=[]
        sta,end=-1,-1
        for i in s:
            if i not in hash_set:
                hash_set.add(i)
            else:
                continue
            a,b=first_end_idx(i,s)
            if sta==-1:
                sta,end=a,b
            elif a<end and b>end:
                end=b
            elif a>=end:
                ans.append(end-sta+1)
                sta,end=a,b
        ans.append(end-sta+1)
        return ans

image.png

给定一种规律 pattern 和一个字符串 str ,判断 str 是否遵循相同的规律。
这里的 遵循 指完全匹配,例如, pattern 里的每个字母和字符串 str 中的每个非空单词之间存在着双向连接的对应规律。
示例1:
输入: pattern = "abba", str = "dog cat cat dog"
输出: true

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/word-pattern
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

class Solution:
    def wordPattern(self, pattern: str, s: str) -> bool:
        word_to_chr={}
        s_list=s.split(' ')
        #pa_list=list(pattern)
        if len(s_list)!=len(pattern):
            
            return False
        for i in range(len(s_list)):
            if s_list[i] not in word_to_chr:
                if pattern[i] not in word_to_chr.values():
                    word_to_chr[s_list[i]]=pattern[i]
                else:
                    #print('hi')
                    return False
            else:
                if word_to_chr[s_list[i]]==pattern[i]:
                    pass
                else:
                    return False
        return True

image.png

自作聪明导致做错

很多时候自作聪明并不是比最终答案做出的努力少,而是努力方向没加以验证,做了错误的努力

给你一个整数 n ,求恰由 n 个节点组成且节点值从 1 到 n 互不相同的 二叉搜索树 有多少种?返回满足题意的二叉搜索树的种数。


image.png
class Solution:
    def __init__(self):
        self.dict_={}
        self.dict_[1]=1
        self.dict_[2]=2
        self.dict_[3]=5
        self.dict_[0]=1
    #动态规划or搜索
    def numTrees(self, n: int) -> int:
        #
        if n==1:
            return 1
        elif n==2:
            return 2
        elif n==3:
            return 5
        else:
            ans=0
            if n in self.dict_:
                return self.dict_[n]
            for i in range(n):
                '''
                if n%2==1 and i==n//2:
                    continue
                '''
                ans+=self.numTrees(i)*self.numTrees(n-i-1)
                #print(ans)
            self.dict_[n]=ans
            return ans



image.png

实属恶心人了,属于是

image.png
class Solution:
    def combinationSum2(self, candidates: List[int], target: int) -> List[List[int]]:
        if sum(candidates)<target:
            return []
        n=len(candidates)
        isvisited=[False]*n
        ans=[]
        hash_set=set()
        def dfs(sum_,i,per):
            if sum_>target:
                return
            if sum_==target:
                t=tuple(sorted(per))
                if t not in hash_set:
                    hash_set.add(t)
                    ans.append([i for i in t])
                return
            for j in range(i,n):
                if not isvisited[j]:
                    isvisited[j]=True
                    per.append(candidates[j])
                    dfs(sum_+candidates[j],j,per)
                    per.pop()
                    isvisited[j]=False
        dfs(0,0,[])
        return ans
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,445评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,889评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,047评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,760评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,745评论 5 367
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,638评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,011评论 3 398
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,669评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,923评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,655评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,740评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,406评论 4 320
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,995评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,961评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,197评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,023评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,483评论 2 342

推荐阅读更多精彩内容