Python-Leetcode精华75做题记录

文章介绍了四个LeetCode编程题目,涉及字符串操作(如合并、反转元音和单词),数组处理(种花问题、分配糖果、交替合并字符串),以及寻找数组中的特定子序列(递增三元子序列)。解题策略包括动态规划、贪心算法和双指针技巧。
摘要由CSDN通过智能技术生成

数组

605. 种花问题

  • 假设有一个很长的花坛,一部分地块种植了花,另一部分却没有。可是,花不能种植在相邻的地块上,它们会争夺水源,两者都会死去。

  • 给你一个整数数组 flowerbed 表示花坛,由若干 01 组成,其中 0 表示没种植花,1 表示种植了花。另有一个数 n ,能否在不打破种植规则的情况下种入 n 朵花?能则返回 true ,不能则返回 false

  • 题解

  • class Solution:
        def canPlaceFlowers(self, flowerbed: List[int], n: int) -> bool:
            flowerbed = [0]+ flowerbed
            flowerbed = flowerbed+[0]
            for i in range(1,len(flowerbed)-1):
                if  flowerbed[i-1] == 0 and flowerbed[i] == 0 and flowerbed[i+1] == 0:
                    n = n-1
                    flowerbed[i] = 1
            return n<=0

    作者:呀类呀类daze 链接:力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台 来源:力扣(LeetCode) 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

补零的做法,今天才发现离扣不用写主函数,,,sos

  • upd 初步看了一下代码随想录 螺旋矩阵没懂 先实操一下


1431. 拥有最多糖果的孩子

  • 给你一个数组 candies 和一个整数 extraCandies ,其中 candies[i] 代表第 i 个孩子拥有的糖果数目。

  • 对每一个孩子,检查是否存在一种方案,将额外的 extraCandies 个糖果分配给孩子们之后,此孩子有 最多 的糖果。注意,允许有多个孩子同时拥有 最多 的糖果数目。

  • 题解

  • class Solution:
    ​
    def kidsWithCandies(self, candies: List[int], extraCandies: int) -> List[bool]:
    ​
    •    result = []
    ​
    •    n = len(candies)
    ​
    •    for i in range(n):
    ​
    •      is_g = True
    ​
    •      for j in range(n):
    ​
    •        if candies[i] + extraCandies < candies[j]:
    ​
    •          is_g = False
    ​
    •          break
    ​
    •      result.append(is_g)   
    ​
    •          
    ​
    •    return `result`

    还有其他思路 比如先取出最多数量糖果的,然后加上附加糖果。

class Solution:
    def kidsWithCandies(self, candies: List[int], extraCandies: int) -> List[bool]:
        maxi = max(candies)
        judge = []
        for i in candies:
            judge.append(i+extraCandies>=maxi)
        return judge

作者:Orust 链接:力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台 来源:力扣(LeetCode) 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

1768. 交替合并字符串

  • 给你两个字符串 word1word2 。请你从 word1 开始,通过交替添加字母来合并字符串。如果一个字符串比另一个字符串长,就将多出来的字母追加到合并后字符串的末尾。

    返回 合并后的字符串

  • 题解

    class Solution:
    ​
    def mergeAlternately(self, word1: str, word2: str) -> str:
    ​
    •    result = []
    ​
    •    n1 = len(word1)
    ​
    •    n2= len(word2)
    ​
    •    if n1 >= n2:
    ​
    •      for i in range(n2):
    ​
    •        result.append(word1[i])
    ​
    •        result.append(word2[i])
    ​
    •      result.extend(word1[n2:])
    ​
    •      
    ​
    •    if n2 > n1:
    ​
    •      for i in range(n1):
    ​
    •        result.append(word1[i])
    ​
    •        result.append(word2[i])
    ​
    •      result.extend(word2[n1:])
    ​
    •    *return ''.join(result) # 空串加入 使result成为字符串*

这道题给的最重要的经验就是,list转str只要加空串''就可以

1071. 字符串的最大公因子

  • 对于字符串 st,只有在 s = t + ... + tt 自身连接 1 次或多次)时,我们才认定 “t 能除尽 s”。

    给定两个字符串 str1str2 。返回 最长字符串 x,要求满足 x 能除尽 str1x 能除尽 str2

    • 有点难的 第一次做没思路

  • 题解

class Solution: def gcdOfStrings(self, str1: str, str2: str) -> str: for i in range(min(len(str1), len(str2)), 0, -1): if (len(str1) % i) == 0 and (len(str2) % i) == 0: if str1[: i] * (len(str1) // i) == str1 and str1[: i] * (len(str2) // i) == str2: return str1[: i] return ''

作者:力扣官方题解 链接:力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台 来源:力扣(LeetCode) 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

  • 还有一个很绝的:

class Solution: def gcdOfStrings(self, str1: str, str2: str) -> str: return str1[: math.gcd(len(str1), len(str2))] if str1 + str2 == str2 + str1 else ''

作者:int_64 链接:力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台 来源:力扣(LeetCode) 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

  • 感觉这道题思路比较难,gcd这个条件比较难想到。

345. 反转字符串中的元音字母

给你一个字符串 s ,仅反转字符串中的所有元音字母,并返回结果字符串。

元音字母包括 'a''e''i''o''u',且可能以大小写两种形式出现不止一次。

  • 题解

  • class Solution:
    ​
    def reverseVowels(self, s: str) -> str:
    ​
    •    **result = list(s) # 圆括号**
    ​
    •    vowels = set("aeiouAEIOU") # 创建元音字母集合
    ​
    •    left = 0
    ​
    •    right = len(s)-1
    ​
    •    while left < right:
    ​
    •      **if result[left] not in vowels: # 用集合来做**
    ​
    •        left +=1
    ​
    •      if result[right] not in vowels:
    ​
    •        right -=1
    ​
    •      if result[left]  in vowels and result[right]  in vowels:
    ​
    •        result[left],result[right] = result[right],result[left]
    ​
    •        left +=1
    ​
    •        right -=1
    ​
    •    return "".join(result)

  • 一开始写错了and 用了&&。。。java后遗症; py没有自增。要+=


151. 反转字符串中的单词

给你一个字符串 s ,请你反转字符串中 单词 的顺序。

单词 是由非空格字符组成的字符串。s 中使用至少一个空格将字符串中的 单词 分隔开。

返回 单词 顺序颠倒且 单词 之间用单个空格连接的结果字符串。

注意:输入字符串 s中可能会存在前导空格、尾随空格或者单词间的多个空格。返回的结果字符串中,单词间应当仅用单个空格分隔,且不包含任何额外的空格。

  • 题解:

  • class Solution:
    ​
    def reverseWords(self, s: str) -> str:
    ​
    •    strlst = s.split() #是列表
    ​
    •    result = []
    ​
    •    for i in range(len(strlst)):
    ​
    •      result.append(strlst[len(strlst)-1-i])
    ​
    •      if i < len(strlst) - 1:
    ​
    •        result.append(' ')
    ​
    •    return ''.join(result)

自己写的题解,str用了split之后会返回列表。strip可以用来删除首尾指定字符。

  • 双指针法:

class Solution:
    def reverseWords(self, s: str) -> str:
        s = s.strip()                            # 删除首尾空格
        i = j = len(s) - 1
        res = []
        while i >= 0:
            while i >= 0 and s[i] != ' ': i -= 1 # 搜索首个空格
            res.append(s[i + 1: j + 1])          # 添加单词
            while i >= 0 and s[i] == ' ': i -= 1 # 跳过单词间空格
            j = i                                # j 指向下个单词的尾字符
        return ' '.join(res)                     # 拼接并返回

作者:Krahets 链接:力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台 来源:力扣(LeetCode) 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

238. 除自身以外数组的乘积

给你一个整数数组 nums,返回 数组 answer ,其中 answer[i] 等于 nums 中除 nums[i] 之外其余各元素的乘积

题目数据 保证 数组 nums之中任意元素的全部前缀元素和后缀的乘积都在 32 位 整数范围内。

不要使用除法,且在 O(*n*) 时间复杂度内完成此题。

  • 难点是不可以用乘法。。。 时间复杂度来看可以用多数组储存

  • 题解(参考了一下别人的

  • class Solution:
    ​
    def productExceptSelf(self, nums: List[int]) -> List[int]:
    ​
    •    n= len(nums)
    ​
    •    result = [1]*n               **# 这里如果不定义数组长度就会报错:result[i] = left[i]*right[i]**
    ​
    •    left,right = n*[1], n*[1]
    ​
    •    for i in range(1,n ):
    ​
    •      left[i] = left[i-1]*nums[i-1]
    ​
    •    for i in range(n-2,-1,-1):
    ​
    •      right[i] = right[i+1]*nums[i+1]
    ​
    •    for i in range(n):
    ​
    •      result[i] = left[i]*right[i]
    ​
    •    return result

334. 递增的三元子序列

给你一个整数数组 nums ,判断这个数组中是否存在长度为 3 的递增子序列。

如果存在这样的三元组下标 (i, j, k) 且满足 i < j < k ,使得 nums[i] < nums[j] < nums[k] ,返回 true ;否则,返回 false

  • 超时的暴力算法:

    class Solution:
    ​
      def increasingTriplet(self, nums: List[int]) -> bool:
    ​
        result=[]
    ​
        isfind = 0
    ​
        for i in range(len(nums)):
    ​
          result.append(nums[i])
    ​
          for j in range(i+1,len(nums)):
    ​
            if result[0] < nums[j]:
    ​
              result.append(nums[j])
    ​
              for k in range(j+1,len(nums)):
    ​
                if result[1] < nums[k]:
    ​
                  isfind = 1
    ​
        if isfind == 1:
    ​
          return True
    ​
        else :
    ​
          return False

  • 优化 : 定长上升子序列(贪心) 利用本题只需要我们判定是否存在长度为 333 的上升子序列,而不需要回答 LIS 最大长度。

    我们可以对 fff 数组进行优化:使用有限变量进行替换(将 fff 数组的长度压缩为 222),数组含义不变,f[1]=xf[1] = xf[1]=x 代表长度为 111 的上升子序列最小结尾元素为 xxx,f[2]=yf[2] = yf[2]=y 代表长度为 222 的上升子序列的最小结尾元素为 yyy。

    从前往后扫描每个 nums[i]nums[i]nums[i],每次将 nums[i]nums[i]nums[i] 分别与 f[1]f[1]f[1] 和 f[2]f[2]f[2] 进行比较,如果能够满足 nums[i]>f[2]nums[i] > f[2]nums[i]>f[2],代表 nums[i]nums[i]nums[i] 能够接在长度为 222 的上升子序列的后面,直接返回 True,否则尝试使用 nums[i]nums[i]nums[i] 来更新 f[1]f[1]f[1] 和 f[2]。f[2]。f[2]。

    这样,我们只使用了有限变量,每次处理 nums[i]nums[i]nums[i] 只需要和有限变量进行比较,时间复杂度为 O(n)O(n)O(n),空间复杂度为 O(1)O(1)O(1)。

    • class Solution:
          def increasingTriplet(self, nums: List[int]) -> bool:
              n = len(nums)
              f = [inf] * 3
              for i in range(n):
                  t = nums[i]
                  if f[2] < t:
                      return True
                  elif f[1] < t < f[2]:
                      f[2] = t
                  elif f[1] > t:
                      f[1] = t
              return False
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值