LeetCode 389. 找不同 | Python

389. 找不同


题目来源:力扣(LeetCode)https://leetcode-cn.com/problems/find-the-difference/

题目


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

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

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

示例 1:

输入:s = "abcd", t = "abcde"
输出:"e"
解释:'e' 是那个被添加的字母。

示例 2:

输入:s = "", t = "y"
输出:"y"

示例 3:

输入:s = "a", t = "aa"
输出:"a"

示例 4:

输入:s = "ae", t = "aea"
输出:"a"

提示:

  • 0 <= s.length <= 1000
  • t.length == s.length + 1
  • st 只包含小写字母

解题思路


思路:计数、位运算、求和

先审题,题目中给定两个字符串 s s s t t t,它们只含小写字母。

其中字符串 t t t 由字符串 s s s 重排,在随机的位置上添加一个字母,现在要求找出 t t t 中被添加的字母。

计数

题目已说明,字符串 t t t 比字符串 s s s 多一个字母,那么我们可以先用数组统计 s s s 的字符出现的次数。

然后开始遍历字符串 t t t,数组中对应字符的次数减 1。当数组中出现负数,那么代表对应的字符就是添加的字母。

具体的代码实现如下。

class Solution:
    def findTheDifference(self, s: str, t: str) -> str:
        # 长度为 26 的数组,用以统计字符出现次数
        str_count = [0] * 26
        # 先遍历 s,统计 s 中字符出现的次数
        for ch in s:
            str_count[ord(ch)-ord('a')] += 1
        # 再遍历 t,将出现字符对应次数减 1,
        # 当出现负值,表示对应的字符就是添加的字母
        for ch in t:
            str_count[ord(ch)-ord('a')] -= 1
            if str_count[ord(ch)-ord('a')] < 0:
                return ch
        
        return ''
复杂度分析
  • 时间复杂度: O ( N ) O(N) O(N) N N N 表示字符串长度。
  • 空间复杂度: O ( ∣ Σ ∣ ) O(|\Sigma|) O(Σ),其中 Σ \Sigma Σ 是字符集,这里字符串中只包含小写字母, ∣ Σ ∣ = 26 |\Sigma|=26 Σ=26。使用长度为 26 26 26 的数组统计字符出现次数。
位运算

这道题中,字符串 t t t 比字符串 s s s 只多了一个字母,那么如果将两个字符串拼接起来,那么就可以转化为求字符串中出现次数为奇数的字符。就如站内的 136 题【136. 只出现一次的数字】(位运算)

那么我们可以用位运算来解决这个问题。

这里再提下异或的性质:二进制位同一位相同则为 0,不同则为 1。关于异或的规律:

  • 任何数与自身异或结果为 0。
  • 任何数与 0 异或结果为本身。

同时,异或满足交换律、结合律(数学符号:⊕)

  • 交换律:a ⊕ b = b ⊕ a
  • 结合律:a ⊕ (b ⊕ c) = (a ⊕ b) ⊕ c

这里使用位运算异或具体的思路如下:

  • 初始化遍历 a n s ans ans 为 0(根据上面异或的第 2 个规律);
  • 遍历开始对两个字符串的字符都进行异或(将字符转换为对应的 ASCII 值);
  • 最终将 a n s ans ans 转换为对应的 ASCII 字符,就是要求的结果。

具体的代码实现如下。

class Solution:
    def findTheDifference(self, s: str, t: str) -> str:
        # 初始化 ans 为 0
        ans = 0
        # 对字符串 s 的字符进行异或
        for ch in s:
            ans ^= ord(ch)
        # 对字符串 t 的字符进行异或
        for ch in t:
            ans ^= ord(ch)
        # 最终结果转换为 ASCII 字符
        return chr(ans)

在 Python 当中,我们可以借助chr()、ord()、map()、reduce()、xor() 这些函数用一行代码来解答这个问题。代码如下。

from operator import xor
from functools import reduce
class Solution:
    def findTheDifference(self, s: str, t: str) -> str:
        return chr(reduce(xor, map(ord, s + t)))

其中 xor()operator 库中,函数返回的是按位异或结果。

reduce() p y t h o n 3. x \rm{python3.x} python3.x 版本中已经移动到 functools 库中,调用前需要导入。

chr()ord()map() 这三者则均为内置函数,可直接调用。

不过在力扣中,大部分常用库已经被自动导入。

这些函数的作用,均可在官方文档中找到相应的解释,如有不理解,不妨翻阅一下。

复杂度分析
  • 时间复杂度: O ( N ) O(N) O(N)
  • 空间复杂度: O ( 1 ) O(1) O(1)
求和

这里借鉴 官方题解 给出的思想。先分别计算字符串 s s s 和字符串 t t t 各个字符对应的 ASCII 码值之和。因为 t t t s s s 只多了一个字母,那么用 t t t 中各个字符的 ASCII 值和减去 s s s 各个字符的 ASCII 值和,最终差值转换为 ASCII 字符即是所求结果。

class Solution:
    def findTheDifference(self, s: str, t: str) -> str:
        add_s = 0
        add_t = 0
        # 计算 s 中各个字符的 ASCII 值和
        for ch in s:
            add_s += ord(ch)
        # 计算 t 中各个字符的 ASCII 值和
        for ch in t:
            add_t += ord(ch)
        # 计算差值,转换为 ASCII 字符
        return chr(add_t - add_s)

这里同样也可以借助 sum()、chr()、ord()、map() 这些函数,用一行代码来尝试实现。

class Solution:
    def findTheDifference(self, s: str, t: str) -> str:
        return chr(sum(map(ord, t))- sum(map(ord, s)))
复杂度分析
  • 时间复杂度: O ( N ) O(N) O(N)
  • 空间复杂度: O ( 1 ) O(1) O(1)

欢迎关注


公众号 【书所集录


如有错误,烦请指出,欢迎指点交流。如果觉得写得还可以,还请点个赞,谢谢。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值