字符串也能看风水?教你用 Swift 一眼看出回文潜力

在这里插入图片描述
在这里插入图片描述

文章目录

    • 摘要
    • 描述
    • 内容分析与实际场景联想
    • 题解答案
    • 题解代码分析
      • 第一步:统计每个字符出现的次数
      • 第二步:筛选出现奇数次的字符数量
      • 第三步:判断奇数次字符是否不超过一个
    • 示例测试及结果
    • 时间复杂度
    • 空间复杂度
    • 总结

摘要

我们这一篇要聊的是 LeetCode 第 266 题,也是一道挺有意思的字符串类题目:判断一个字符串的某个排列是否可以构成回文(Palindrome)。文章不仅会提供 Swift 的解法,还会结合现实场景和边界情况,从为什么要这么判断,到代码的优化点一一讲清楚。最后还有可运行的 Demo 和复杂度分析,带你一步一步拆解问题背后的逻辑。

描述

这道题目标很明确:给你一个字符串,问你这个字符串的某个排列,有没有可能是一个回文字符串。注意这里不是直接判断它本身是否是回文,而是它的某个重新排列之后的版本是否可以。

题目输入输出示例:

输入: "code"
输出: false

输入: "aab"
输出: true

输入: "carerac"
输出: true

内容分析与实际场景联想

先说什么是回文字符串:
就是正着读、反着读都一样的字符串,比如 "abba""racecar"。回文结构本身是一种对称性,所以无论左右翻转,它的字符顺序保持一致。

那某个排列能构成回文,满足什么条件?
我们观察几个例子就能发现一个规律:

  • "aab" 可以变成 "aba",它是回文。
  • "carerac" 可以变成 "racecar",也没问题。
  • "code" 无论怎么排列,都不会变成回文。

归根结底,这和“字符的出现次数”有关。
对于一个字符串来说:

  • 如果它的长度是偶数,那么每个字符都必须出现偶数次;
  • 如果长度是奇数,那么最多只能有一个字符出现奇数次,其他都必须是偶数次。

比如:

字符串 字符频率 奇数个数 是否可以回文
“aab” a:2, b:1 1 ✅ 是
“code” c:1, o:1, d:1, e:1 4 ❌ 否
“carerac” c:2, a:2, r:2, e:1 1 ✅ 是

这个统计逻辑,正是我们解题的核心。

题解答案

func canPermutePalindrome(_ s: String) -> Bool {
    var charCount = [Character: Int]()
    for char in s {
        charCount[char, default: 0] += 1
    }
    let oddCount = charCount.values.filter { $0 % 2 != 0 }.count
    return oddCount <= 1
}

题解代码分析

我们的思路可以拆成几个关键步骤:

第一步:统计每个字符出现的次数

for char in s {
    charCount[char, default: 0] += 1
}

这里我们使用 Swift 字典 charCount 来记录每个字符出现了多少次。

第二步:筛选出现奇数次的字符数量

let oddCount = charCount.values.filter { $0 % 2 != 0 }.count

我们用 .filter 方法把所有出现奇数次的字符数量找出来,然后看总共有几个。

第三步:判断奇数次字符是否不超过一个

return oddCount <= 1

如果最多只有一个字符是奇数次,那就说明这字符串是有机会通过某种排列构成回文的。

示例测试及结果

print(canPermutePalindrome("code"))     // 输出: false
print(canPermutePalindrome("aab"))      // 输出: true
print(canPermutePalindrome("carerac"))  // 输出: true
print(canPermutePalindrome(""))         // 输出: true
print(canPermutePalindrome("a"))        // 输出: true

额外补充两个边界测试:

  • 空字符串 "" 应该返回 true,因为没有字符,也是一种“对称”;
  • 单个字符,比如 "a" 也能构成回文(自己和自己反过来一样)。

时间复杂度

  • O(n),其中 n 是字符串的长度。我们只遍历一次字符串来统计字符频率,再遍历字典的值判断奇数次个数。

空间复杂度

  • O(1),因为我们最多只会统计 26 个英文字母(或者 128 个 ASCII 字符),使用的额外空间和输入长度无关,是固定的。

总结

这题虽然简单,但挺有启发的。能不能构成回文,其实并不是关于顺序的判断,而是关于“字符频率分布”的判断

我们做算法题,很多时候就是学会“转换问题视角”——一开始是字符串排列的问题,最终却转化成了“统计奇偶个数”的问题。这个套路,很多字符串相关的面试题都会用到。

而且这道题还挺贴近实际,比如在自然语言处理、密码学、数据压缩中,“字符串是否可对称”本身就是一种有价值的判断标准。

你可能感兴趣的:(Swift,swift,开发语言,ios)