每日一题-202. 快乐数

今天是2020年4月30日,星期四。四月的最后一天啦,五月运气好好呦。

题目描述

编写一个算法来判断一个数 n 是不是快乐数。

「快乐数」定义为:对于一个正整数,每一次将该数替换为它每个位置上的数字的平方和,然后重复这个过程直到这个数变为 1,也可能是 无限循环 但始终变不到 1。如果 可以变为  1,那么这个数就是快乐数。

如果 n 是快乐数就返回 True ;不是,则返回 False 。

示例:

输入:19
输出:true
解释:
12 + 92 = 82
82 + 22 = 68
62 + 82 = 100
12 + 02 + 02 = 1

题目分析

在本题目中,需要理解的关键是「无限循环 但始终变不到1」,在这种情况中一定存在循环节,即当前的数字n如果在之前已经出现过,那么一定无法变到1,这种则可以返回false。

在Java中可以借助HashSet来进行计算结果的去重。若当前数字已经在HashSet中出现过,则返回false;否则加入HashSet,进行下一轮的去重。

另一种方法则使用快慢指针的方法,每个中间计算的值都可以认为是链表中的一个节点,如果最后不能为1,则一定存在循环。则使用快慢指针验证链表中是否存在环。

参考代码

  • 借用HashSet
/**
 * 依靠hashset来存储之前计算过的值,如果已经发现了之前出现过的值,肯定不能到1
 *
 * @param n
 * @return
 */
public boolean isHappy(int n) {
    if (n == 1) {
        return true;
    }

    Set<Integer> set = new HashSet<>();
    set.add(n);
    return isHappy(n, set);
}

private boolean isHappy(int n, Set<Integer> set) {
    if (n == 1) {
        return true;
    }
    List<Integer> list = new ArrayList<>();
    int tmp = n;
    while (tmp != 0) {
        list.add(tmp % 10);
        tmp = tmp / 10;
    }
    int next = 0;
    for (Integer integer : list) {
        next += (integer * integer);
    }

    if (set.contains(next)) {
        return false;
    } else {
        set.add(next);
        return isHappy(next, set);
    }

}
  • 快慢指针
/**
 * 使用快慢指针
 * 每个中间计算的值都可以认为是链表中的一个节点,如果最后不能为1,则一定存在循环。
 * 则使用快慢指针查找链表中是否存在换
 *
 * @param n
 * @return
 */
public boolean isHappy2(int n) {
    if (n == 1) {
        return true;
    }

    int slow = n;
    int fast = squareSum(n);
    while (slow != fast) {
        slow = squareSum(slow);
        fast = squareSum(squareSum(fast));
    }

    return slow == 1;
}

private int squareSum(int n) {
    int sum = 0;
    while(n > 0){
        int digit = n % 10;
        sum += digit * digit;
        n /= 10;
    }
    return sum;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值