【LeetCode】202. 快乐数

leetcode

 

解题思路

快乐数问题的核心在于循环检测,主要有两种解法:

  1. 哈希集合法:记录所有出现过的数字,若重复出现则判定为循环(时间复杂度 O(n),空间复杂度 O(n))。
  2. 快慢指针法:利用龟兔赛跑算法检测循环,无需额外存储空间(时间复杂度 O(n),空间复杂度 O(1))。

以下采用快慢指针法实现,这是空间最优的解法。


关键步骤

  1. 平方和计算:将数字按位分解,计算各位平方和(如 19 → 1²+9²=82)。
  2. 循环检测
    • 定义慢指针 slow(每次计算一次平方和)和快指针 fast(每次计算两次平方和)。
    • 若快慢指针相遇且值为 1,则为快乐数;否则存在循环,返回 false。

Golang代码实现

func isHappy(n int) bool {
    // 边界条件:直接返回1的情况
    if n == 1 {
        return true
    }

    // 快慢指针初始化
    slow, fast := n, bitSquareSum(n)
    
    // 循环检测(快指针可能先到1)
    for fast != 1 && slow != fast {
        slow = bitSquareSum(slow)        // 慢指针走一步
        fast = bitSquareSum(bitSquareSum(fast)) // 快指针走两步
    }
    
    return fast == 1
}

// 计算数字的各位平方和
func bitSquareSum(n int) int {
    sum := 0
    for n > 0 {
        digit := n % 10     // 取个位数
        sum += digit * digit
        n /= 10             // 移除已处理的位数
    }
    return sum
}

复杂度分析

指标说明
时间复杂度 O(n) 最坏情况下遍历数字链长度
空间复杂度 O(1) 仅使用固定变量,无额外存储

代码解析

  1. 快慢指针逻辑

    • 快指针每次移动两步,慢指针移动一步。若存在循环,两者必定相遇。
    • 示例:对于 n=2,计算链为 2 → 4 → 16 → 37 → 58 → 89 → 145 → 42 → 20 → 4,快慢指针最终会在 4 处相遇,返回 false。
  2. 平方和计算函数

    • 通过取余和整除操作逐位处理数字(如 19 → 1和9 → 1+81=82)。
  3. 边界处理

    • 若输入为 1,直接返回 true。
    • 若快指针先到达 1,立即终止循环(如 n=7 的快乐数链)。

运行示例验证

func main() {
    fmt.Println(isHappy(19))  // 输出: true(示例1)
    fmt.Println(isHappy(2))   // 输出: false(示例2)
    fmt.Println(isHappy(7))   // 输出: true(快乐数)
    fmt.Println(isHappy(4))   // 输出: false(进入循环)
}

扩展讨论

  1. 数学规律优化
    不快乐数最终会进入 4 → 16 → 37 → 58 → 89 → 145 → 42 → 20 → 4 的循环。若检测到 4 可直接返回 false:

    func bitSquareSum(n int) int {
        sum := 0
        for n > 0 {
            digit := n % 10
            sum += digit * digit
            n /= 10
            if sum > 4 { // 提前终止不必要的计算
                break
            }
        }
        return sum
    }

    该优化可减少部分计算次数,但需权衡条件判断的开销。

  2. 哈希集合法对比

    func isHappyHash(n int) bool {
        seen := make(map[int]bool)
        for n != 1 && !seen[n] {
            seen[n] = true
            n = bitSquareSum(n)
        }
        return n == 1
    }

    该方法更直观,但需额外 O(n) 空间存储已出现数字。


总结

快慢指针法通过循环检测机制空间优化,成为解决快乐数问题的标准解法。该实现兼顾效率与代码简洁性,完美覆盖所有测试用例。

 
posted @ 2025-03-29 14:37  云隙之间  阅读(53)  评论(0)    收藏  举报