# 202. 快乐数 - 力扣题解最佳实践 访问原文链接:[202. 快乐数 - 力扣题解最佳实践](https://leetcoder.net/zh/leetcode/202-happy-number),体验更佳! 力扣链接:[202. 快乐数](https://leetcode.cn/problems/happy-number), 难度:**简单**。 ## 力扣“202. 快乐数”问题描述 编写一个算法来判断一个数 `n` 是不是快乐数。 「**快乐数**」 定义为: - 对于一个正整数,每一次将该数替换为它每个位置上的数字的平方和。 - 然后重复这个过程直到这个数变为 `1`,也可能是 **无限循环** 但始终变不到 `1`。 - 如果这个过程 **结果为** `1`,那么这个数就是快乐数。 - 如果 `n` 是 *快乐数* 就返回 `true` ;不是,则返回 `false` 。 ### [示例 1] **输入**: `n = 19` **输出**: `true` **解释**:

12 + 92 = 82
82 + 22 = 68
62 + 82 = 100
12 + 02 + 02 = 1

### [示例 2] **输入**: `n = 2` **输出**: `false` ### [约束] - `1 <= n <= 2^31 - 1` ## 思路 1. 递归调用`isHappy(n)`比较方便,每次只需要生成新的`n`作为参数。 2. 如果`n`已经出现过了,说明进入了循环,`return false`。可以用`Set`保存已经出现过的`n`。 3. Go是迭代解法,其他语言都是递归解法。 ## 步骤 1. 生成新的`n`作为`isHappy()`的参数。 ```javascript let sum = 0 for (const digit of n.toString()) { sum += Math.pow(Number(digit), 2) } // omitted code return isHappy(sum) ``` 2. 如果`n`已经出现过了,说明进入了循环,`return false`。可以用`Set`保存已经出现过的`n`。 ```javascript var isHappy = function (n, appearedNums) { appearedNums ||= new Set() // 1 let sum = 0 for (const digit of n.toString()) { sum += Math.pow(Number(digit), 2) } if (sum == 1) { return true } if (appearedNums.has(sum)) { // 2 return false } appearedNums.add(sum) // 3 return isHappy(sum, appearedNums) }; ``` ## 复杂度 - 时间复杂度: `O(log N)`. - 空间复杂度: `O(log N)`. ## Java ```java class Solution { private HashSet appearedNums = new HashSet<>(); public boolean isHappy(int n) { appearedNums.add(n); var sum = 0; for (var digit : String.valueOf(n).toCharArray()) { sum += Math.pow(digit - '0', 2); } if (sum == 1) { return true; } if (appearedNums.contains(sum)) { return false; } return isHappy(sum); } } ``` ## Python ```python class Solution: def __init__(self): self.appeared_nums = set() def isHappy(self, n: int) -> bool: self.appeared_nums.add(n) number = sum([int(digit) ** 2 for digit in str(n)]) if number == 1: return True if number in self.appeared_nums: return False return self.isHappy(number) ``` ## JavaScript ```javascript var isHappy = function (n, appearedNums) { appearedNums ||= new Set() let sum = 0 for (const digit of n.toString()) { sum += Math.pow(Number(digit), 2) } if (sum == 1) { return true } if (appearedNums.has(sum)) { return false } appearedNums.add(sum) return isHappy(sum, appearedNums) }; ``` ## C# ```csharp public class Solution { HashSet appearedNums = new HashSet(); public bool IsHappy(int n) { appearedNums.Add(n); int sum = 0; foreach (char digit in n.ToString().ToCharArray()) sum += (int)Math.Pow(digit - '0', 2); if (sum == 1) return true; if (appearedNums.Contains(sum)) return false; return IsHappy(sum); } } ``` ## Go ```go func isHappy(n int) bool { // Use map to track seen numbers seen := make(map[int]bool) for n != 1 && !seen[n] { seen[n] = true n = sumOfSquaredDigits(n) } return n == 1 } func sumOfSquaredDigits(n int) int { sum := 0 nStr := strconv.Itoa(n) for i := 0; i < len(nStr); i++ { digit := int(nStr[i] - '0') sum += digit * digit } return sum } ``` ## C++ ```cpp class Solution { public: bool isHappy(int n) { if (n == 1) { return true; } if (appeared_nums_.count(n)) { return false; } appeared_nums_.insert(n); return isHappy(getSum(n)); } private: unordered_set appeared_nums_; int getSum(int n) { string n_str = to_string(n); int sum = 0; for (char digit : n_str) { sum += (digit - '0') * (digit - '0'); } return sum; } }; ``` ## Ruby ```ruby def is_happy(n, appeared_nums = Set.new) return true if n == 1 return false if appeared_nums.include?(n) appeared_nums.add(n) sum = n.to_s.chars.map { |digit| digit.to_i ** 2 }.sum is_happy(sum, appeared_nums) end ``` ## Other languages ```java // Welcome to create a PR to complete the code of this language, thanks! ``` 亲爱的力扣人,为了您更好的刷题体验,请访问 [leetcoder.net](https://leetcoder.net/zh)。 本站敢称力扣题解最佳实践,终将省你大量刷题时间! 原文链接:[202. 快乐数 - 力扣题解最佳实践](https://leetcoder.net/zh/leetcode/202-happy-number). GitHub 仓库: [f*ck-leetcode](https://github.com/fuck-leetcode/fuck-leetcode).