1. 简介

回文串是指正读和反读都相同的单词、短语、数字或字符序列。✅ 换句话说,字符串反转后仍与原串一致。例如 "racecar" 就是一个典型的回文串——无论从左到右还是从右到左读,结果都一样。

本文将介绍在 Kotlin 中判断字符串是否为回文串的几种常用方法。这些方法各有特点,在实际开发中可根据场景灵活选择,避免踩坑 ❌。

2. 测试用例设计

为了验证每种方法的正确性,我们准备以下测试数据:

是回文串:

  • racecar
  • redivider
  • 3553
  • tattarrattat

非回文串:

  • palindrome
  • sever

这些用例覆盖了常见字母组合和数字,有助于全面检验算法逻辑。

3. 使用循环判断

最直观的方法是使用双指针技术(two-pointer technique),从字符串两端向中间逐对比较字符。

fun isPalindrome(str: String): Boolean {
    var start = 0
    var end = str.length - 1
    while (start < end) {
        if (str[start] != str[end]) {
            return false
        }
        start++
        end--
    }
    return true
}

📌 核心思路:

  • 初始化两个索引:start 指向开头,end 指向末尾
  • start < end 时持续比较对应位置字符
  • 一旦发现不匹配立即返回 false
  • 成功遍历到中间则说明是回文串

测试代码如下:

@Test
fun `palindrome check using loop function`(){
    assertTrue(isPalindrome("racecar"))
    assertTrue(isPalindrome("redivider"))
    assertFalse(isPalindrome("palindrome"))
    assertFalse(isPalindrome("sever"))
    assertTrue(isPalindrome("3553"))
    assertTrue(isPalindrome("tattarrattat"))
}

⚠️ 注意:此方法时间复杂度为 O(n/2),空间复杂度为 O(1),效率高且无需额外存储,适合处理大字符串。

4. 使用 reversed() 内置函数

Kotlin 提供了简洁的字符串反转 API —— reversed(),我们可以直接利用它进行对比。

fun isPalindromeWithBuiltInFunction(str: String): Boolean {
    val reversedStr = str.reversed()
    return str == reversedStr
}

📌 特点分析:

  • ✅ 代码极其简洁,可读性强
  • ❌ 需要创建新的字符串对象,内存开销为 O(n)
  • ⚠️ 在性能敏感场景下需谨慎使用,尤其是长字符串

对应的单元测试:

@Test 
fun `palindrome check using built in function`(){ 
    assertTrue(isPalindromeWithBuiltInFunction("racecar"))
    assertTrue(isPalindromeWithBuiltInFunction("redivider"))
    assertFalse(isPalindromeWithBuiltInFunction("palindrome"))
    assertFalse(isPalindromeWithBuiltInFunction("sever"))
    assertTrue(isPalindromeWithBuiltInFunction("3553"))
    assertTrue(isPalindromeWithBuiltInFunction("tattarrattat")) 
}

💡 小贴士:虽然写起来爽,但在高频调用或大数据量场景下,这种“一行流”写法可能成为性能瓶颈。

5. 使用递归实现

递归方式通过不断缩小问题规模来求解:每次比较首尾字符,然后对去掉首尾后的子串继续判断。

fun isPalindromeUsingRecursion(str: String): Boolean {
    if (str.length <= 1) {
        return true
    }
    if (str.first() != str.last()) {
        return false
    }
    return isPalindromeUsingRecursion(str.substring(1, str.length - 1))
}

📌 执行流程:

  1. 终止条件:空串或单字符 → 返回 true
  2. 比较首尾字符 → 不同则返回 false
  3. 否则递归处理子串 [1..length-2]

测试用例:

@Test fun `palindrome check using recursion`(){
    assertTrue(isPalindromeUsingRecursion("racecar"))
    assertTrue(isPalindromeUsingRecursion("redivider"))
    assertFalse(isPalindromeUsingRecursion("palindrome"))
    assertFalse(isPalindromeUsingRecursion("sever"))
    assertTrue(isPalindromeUsingRecursion("3553"))
    assertTrue(isPalindromeUsingRecursion("tattarrattat"))
}

⚠️ 警告:该方法存在明显缺陷:

  • 每次递归都会创建新字符串(substring
  • 调用栈深度可达 n/2,极端情况下可能引发 StackOverflowError
  • 时间和空间复杂度均为 O(n),不推荐用于生产环境

6. 总结

本文系统梳理了 Kotlin 中判断回文串的三种主流方法:

方法 时间复杂度 空间复杂度 优点 缺点
循环双指针 O(n) O(1) 高效、稳定 略显冗长
reversed() O(n) O(n) 简洁易懂 占用额外内存
递归 O(n) O(n) 逻辑清晰 易栈溢出

✅ 推荐实践:

  • 日常开发首选循环法,兼顾性能与可维护性
  • 快速原型或脚本场景可用 reversed() 写法提升开发效率
  • 递归仅作学习理解之用,慎用于线上服务

所有示例代码及完整测试用例已托管至 GitHub:https://github.com/Baeldung/kotlin-tutorials/tree/master/core-kotlin-modules/core-kotlin-strings-3


原始标题:Check if a String Is a Palindrome in Kotlin

« 上一篇: KDoc 简介
» 下一篇: SQLDelight 使用指南