程序员面试金典 02 判定是否互为字符重排

57 阅读2分钟

题目描述

给定两个由小写字母组成的字符串 s1 和 s2,请编写一个程序,确定其中一个字符串的字符重新排列后,能否变成另一个字符串。

示例 1:
输入: s1 = "abc", s2 = "bca"
输出: true

示例 2:
输入: s1 = "abc", s2 = "bad"
输出: false

说明:
0 <= len(s1) <= 100
0 <= len(s2) <= 100

根据题意, 如果一个字符串重排后可以变成另一个字符串, 那个这2个字符串中所有字符的种类和数量应该是相同的, 我们可以根据这个特点进行解题

解题思路1:

对2个字符串分别进行排序, 看排序后的字符串是否完全相同, 涉及到排序的话, 时间复杂度就会变成至少O(NlogN)

示例代码

def CheckPermutation1(self, s1: str, s2: str) -> bool:
    return sorted(list(s1)) == sorted(list(s2))

解题思路2:

我们可以将第二个字符串转为数组, 并对第一个字符串进行遍历, 每遍历一个字符, 就看数组中是否包含当前元素, 如果包含就从数组中删除. 当第一个字符串遍历结束后, 数组为空, 则表示2个字符串可以进行重排

示例代码

def CheckPermutation(self, s1: str, s2: str) -> bool:
    if len(s1) != len(s2): return False
    list2 = list(s2)
    for c in s1:
        if c in list2:
            list2.remove(c)
    return len(list2) == 0

解题思路3:

同样是计算字符个数的思路, 我们将s1的每个字符进行统计, 放进一个数组中 (做加法), 在与s2的每个字符做对比 (做减法), 根据最终根据数组判断结果. 这个思路的时间复杂度为 O(N)

示例代码

def CheckPermutation(self, s1: str, s2: str) -> bool:
    if len(s1) != len(s2): return False
    # 声明一个存储数组
    count_list = [0] * 26
    # s1 进行 加 操作, 记录个数
    for c in s1:
        count_list[ord(c) - 97] += 1
    # s2 进行 减 操作, 进行去重
    for c in s2:
        count_list[ord(c) - 97] -= 1
    # 根据最终的数组进行判断
    for c in count_list:
        if c != 0:
            return False
    return True