python - Leetcode「基础编程能力50题」喂饭题解:1768、389、28、242、459

本系列面向刚学会基础语法、还没有刷题经验的同学,通过足够详细的注解展示此前在基础的python系列中学到的知识点如何在代码中应用以解决问题,得到更深入的理解和基础做题经验。开头会写得尽量详细,往后则逐步只挑核心,纯小白入,不必畏难,祝大家刷题愉快!

1768.交替合并字符串

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

返回 合并后的字符串 。

题目拆解

目标是:将word1与word2序列中的元素,一边一个地添加到新字符串里。超出的部分,直接全部添加。

因此:
通过循环将字符串中的元素逐个输出
循环边界是以最长的字符串长度为边界

通过判断限定输出条件,以此来控制长出另一个字符串的部分的输出是连续的。

完整题解

class Solution:
    def mergeAlternately(self, word1: str, word2: str) -> str:
        m, n = len(word1), len(word2)
        i = j = 0

        ans = list()
        while i < m or j < n:
            if i < m:
                ans.append(word1[i])
                i += 1
            if j < n:
                ans.append(word2[j])
                j += 1
        
        return "".join(ans)

作者:力扣官方题解
链接:https://leetcode.cn/problems/merge-strings-alternately/solutions/1913930/jiao-ti-he-bing-zi-fu-chuan-by-leetcode-ac4ih/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

逐行注释

class Solution:

定义了一个名为 Solution 的类,后续的方法会封装在这个类中,通常在算法题中,会用这种方式来组织解决问题的代码。

def mergeAlternately(self, word1: str, word2: str) -> str:

Solution 类中定义了一个名为 mergeAlternately 的实例方法。self 是对类实例的引用;word1word2 是该方法的两个参数,类型注解表明它们都是字符串;-> str 表示这个方法的返回值类型是字符串。

m, n = len(word1), len(word2)

计算字符串 word1 的长度并赋值给 m,计算字符串 word2 的长度并赋值给 n,后续会用这两个变量来控制循环次数。

i = j = 0

初始化两个索引变量 ij,分别用于遍历字符串 word1word2,初始值都设为 0

ans = list()

创建一个空列表 ans,用于存储交替合并后的字符。

while i < m or j < n:

设置一个循环条件,只要 i 小于 word1 的长度 m 或者 j 小于 word2 的长度 n,循环就会继续执行,确保能处理完两个字符串中较长的那个字符串的所有字符。

if i < m:
    ans.append(word1[i])
    i += 1

如果 i 小于 word1 的长度 m,说明 word1 还有未处理的字符,就将 word1 中索引为 i 的字符添加到列表 ans 中,然后将 i 的值加 1,指向下一个字符。append():向列表末尾添加任意类型的元素,使用方法:列表名.append(字符)

if j < n:
    ans.append(word2[j])
    j += 1

如果 j 小于 word2 的长度 n,说明 word2 还有未处理的字符,就将 word2 中索引为 j 的字符添加到列表 ans 中,然后将 j 的值加 1,指向下一个字符。

return "".join(ans)

循环结束后,列表 ans 中已经存储了交替合并后的字符,使用 join 方法将列表中的字符连接成一个字符串并返回,作为最终交替合并后的结果。 join()的使用方法:"连接符,可以为空"``.join(列表名)

389.找不同

给定两个字符串 s 和 t ,它们只包含小写字母。

字符串 t 由字符串 s 随机重排,然后在随机位置添加一个字母。

请找出在 t 中被添加的字母。

题目拆解

找出被添加的字母,由于字符串是随机重排并且添加也是随机添加的,因此并不好用逐个对比的办法处理。

但既然是随机顺序,可以想到:字典。
因此可以先想办法完成对每个字符出现的次数进行计数,以键值对的形式储存在字符串各自对应的字典里,然后再通过键去找对应值,判断是否相等。出现次数相等的说明不是后来添加的。

完整题解

class Solution(object):
    def findTheDifference(self, s, t):
        """
        :type s: str
        :type t: str
        :rtype: str
        """
        # 使用Counter计算两个字符串中字符的频率
        counter_s = Counter(s)
        counter_t = Counter(t)
        
        # 找到在counter_t中存在但在counter_s中不存在或者数量更多的字符
        for char in counter_t:
            if counter_t[char] > counter_s.get(char, 0):
                return char

逐行注释

  1. 统计字符频率
# 使用Counter计算两个字符串中字符的频率
counter_s = Counter(s)
counter_t = Counter(t)
  • 使用Counter为字符串s中的每个字符创建一个计数器,记录每个字符出现的次数,最终得到的是一个字典。例如,如果 s = "abc",则 counter_s{'a': 1, 'b': 1, 'c': 1}
  • counter_t = Counter(t):同理,统计字符串 t 中每个字符的出现次数,并将结果存储在 counter_t 中。
  1. 查找多出来的字符
# 找到在counter_t中存在但在counter_s中不存在或者数量更多的字符
for char in counter_t:
    if counter_t[char] > counter_s.get(char, 0):
        return char
  • for char in counter_t::遍历 counter_t 中的每个键(即字符串 t 中的每个不同字符)。
  • counter_t[char]:根据键索引 char 找值,获取字符 char 在字符串 t 中出现的次数。
  • counter_s.get(char, 0):使用 get 方法从 counter_s 中获取字符 char 出现的次数。如果 char 不在 counter_s 中,get 方法会返回默认值 0
  • if counter_t[char] > counter_s.get(char, 0)::counter_t如果字符 char 在字符串 t 中出现的次数比在字符串 s 中出现的次数多,说明这个字符就是字符串 t 中多出来的字符。
  • return char:一旦找到多出来的字符,就立即返回该字符。

28. 找出字符串中第一个匹配项的下标

给你两个字符串 haystack 和 needle ,请你在 haystack 字符串中找出 needle 字符串的第一个匹配项的下标(下标从 0 开始)。如果 needle 不是 haystack 的一部分,则返回 -1 。

题目拆解

目标是:在h序列中找到符合n的子序列
所以也就是说,在h序列里逐个切出长度与n相等的子序列,然后与n相比较
如果相等,输出首个符合的字符下标;如果遍历完仍然不符合,输出-1
特殊情况:n序列长度0

因此:
切出长度与n相等的子序列,然后比较
循环边界是h的长度减去n的长度+1
加上特殊情况

完整题解

class Solution:
    def strStr(self, haystack: str, needle: str) -> int:
    
        i = 0
        if len(needle)==0:
            return 0
        for  i in range(len(haystack)-len(needle)+1):
            if haystack[i:i+len(needle)] == needle:
                return i
        return -1

逐行注释

单拎特殊情况:

 if len(needle)==0:
            return 0

切片,一直循环到卡最后一个子序列:

for  i in range(len(haystack)-len(needle)+1):     

判断是否相等,是则输出目标值

            if haystack[i:i+len(needle)] == needle:
                return i

直到循环结束都没有返回i,就返回-1

 		return -1

242. 有效的字母异位词

给定两个字符串 s 和 t ,编写一个函数来判断 t 是否是 s 的 字母异位词。

示例 1:

输入: s = “anagram”, t = “nagaram”
输出: true
示例 2:

输入: s = “rat”, t = “car”
输出: false

题目拆解

与前面的389.找不同类似,也是无序元素组合,可以用一样的方法通过字典来存储键键值对,直接比较两个字典是否相等即可。

完整代码

class Solution:
    def isAnagram(self, s: str, t: str) -> bool:
        counter_s = Counter(s)
        counter_t = Counter(t)
  
        return counter_s == counter_t

459. 重复的子字符串

给定一个非空的字符串 s ,检查是否可以通过由它的一个子串重复多次构成。

示例 1:
输入: s = “abab”
输出: true
解释: 可由子串 “ab” 重复两次构成。

示例 2:
输入: s = “aba”
输出: false

题目拆解

这次是有序的了,不能参考前面无序集合的方法了。

特定技巧:滑动窗口
在这里的应用就是,当一个字符串str自身拼接,得到s_double = str + str后,再去掉第一个字符和最后一个字符,进一步得到修剪后的自身拼接字符串s_trimmed,此时能在s_trimmed里找到这个字符串str,说明这个字符串能够由某个子串重复拼接得到。

要理解这个定义的话,就假设str是最简单的、仅由子串abc重复两次得到的abcabc;
然后,将其double得到abcabcabcabc;
此时,去掉首尾各一个字符,得到bcabcabcab;
可以发现,在其中仍然能找到abcabc。

因markdown画图不便,就不补充了,但用图像会更好理解。比如绿格子接红格子作为子串,重复几次后去掉头尾格子,然后再拿原始字符串格子段滑动着对比。

完整代码

class Solution:
    def repeatedSubstringPattern(self, s: str) -> bool:
        # 创建新的字符串 str = S + S
        str_double = s + s
        
        # 去除首尾字符
        str_trimmed = str_double[1:-1]
        
        # 检查去除首尾字符后的字符串是否包含原字符串
        return s in str_trimmed
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值