leetcode题202快乐数,java解答,不断优化到beate100%

48 篇文章 0 订阅

一、问题描述:

快乐数

CategoryDifficultyLikesDislikes
algorithmsEasy (62.47%)868-
Tags

hash-table | math

Companies

airbnb | twitter | uber

编写一个算法来判断一个数 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 <= 231 - 1

Discussion | Solution

二、题解:

麒麒先说明一下,题解1和题解2都没有beat100%,题解3才优化到beat100%

麒麒的思路1:

主要思路是先将取n的字符串形式s,再遍历s,其中使用HashMap类型的变量map的key来保存s的元素,value来保存个数,于是然后再遍历map,将key对应的元素处理,逐个平方相加再乘于value个数就得到新的n值。当n的小于10时,判断n是否等于1,是,则返回true;反之添加到集合set里面,如果set以及存在了,那么就返回false.

前提引入:

  • 先使用一个集合set来保存n小于10的情况,当小于10,如果没有等于1,那么就变成该小于10的值;
  • s字符串类型变量来保存n的字符串形式;
  • 使用HashMap<Character, Integer>类型的map来处理s的每一个元素

分析过程:

处理n<10的过程:
  • 因为每次处理后的n最终一定会小于10,因此在外层循环的结构体里使用一个判断当(n小于10时),如果等于1则返回true,反之,则添加到集合set里面,如果set也添加不了,就说明该n值重复了,题目的n并不是快乐数
处理n>10的过程:
  • 先构造n的字符串形式s,再逐个遍历s的字符c,遍历时,
  • 当字符c不存在于map的key里面,就添加该key,并且相应的value赋值为1;
  • 如果map的key有值,就对应的value加1;
  • 更新n值(先改为0);
  • 遍历该map:for (char c : map.keySet())
    • 定义变量num为n的某一位数:int num = c - '0';
    • 取该位数的个数,用count来记录:int count = map.get(c);
    • map的keySet的每个值的遍历时都要跟新n:n += num * num * count;
    • 每一次都需要清空map,防止原来的值影响。
xin麒的题解1
class Solution {
    public boolean isHappy(int n) {
        HashMap<Character, Integer> map = new HashMap<>();
        HashSet<Integer> set = new HashSet<>();
        while (true) {
            if(n < 10){
                if(n == 1){return true;}
                if(!set.add(n)){
                    return false;
                }
            }
            String s = n + "";
            for (char c : s.toCharArray()) {
                if (map.containsKey(c)) {
                    int i = map.get(c);
                    map.replace(c, i + 1);
                } else {
                    map.put(c, 1);
                }
            }
            n = 0;
            for (char c : map.keySet()) {
                int count = map.get(c);
                int num = c - '0';
                n += num * num * count;
            }
            map.clear();
        }

    }
}
运行:

在这里插入图片描述

优化思路2:

优化思路:寻找出n<10时可以满足最终结果为1的整数(放到idea里面测试啦);然后就可以在题解里改变一下判断条件:在循环迭代过程中使得n<10时,当n为17,便返回true;反之false.(注意,该题比较特殊,因此可以这样优化。)

如下图:

在这里插入图片描述

xin麒的题解3(与上面的对比仅仅提升1ms):
class Solution {
    public boolean isHappy(int n) {
        HashMap<Character, Integer> map = new HashMap<>();
        while (true) {
            if(n < 10){
                if(n == 1 || n == 7){
                    return true;
                }else{
                    return false;
                }
            }
            String s = n + "";
            for (char c : s.toCharArray()) {
                if (map.containsKey(c)) {
                    int i = map.get(c);
                    map.replace(c, i + 1);
                } else {
                    map.put(c, 1);
                }
            }
            int sum = 0;
            for (char c : map.keySet()) {
                int count = map.get(c);
                int num = c - '0';
                sum += num * num * count;
            }
            n = sum;
            map.clear();
        }

    }
}

(但是还是beat9.01%,xin麒哭了)运行:

在这里插入图片描述

xin麒的题解3:

还是换回普通思路比较好,麒麒终于成功了,下面题解的思路分析和xin麒写的这片文章的实际上一样的:
leetcode使用java解题202快乐数,beat100%

还有的是这个还是有些冗余的代码,于是麒麒打算后面找时间优化下。

class Solution {
    public boolean isHappy(int n) {
        HashSet<Integer> set = new HashSet<>();
        while (true) {
            if(n <= 10){
                if(n == 1 || n == 7 || n == 10){
                    return true;
                }else{
                    return false;
                }
            }
            int sum = 0;
            int count = 0;
            while (n >= 10) {
                int ren = n % 10;
                if (ren != 0){
                    count = 1;
                }
                sum += ren * ren;
                n /= 10;
            }
            if (count == 0 && n == 10){return true;}
            sum += n * n;
            n = sum;
        }
    }
}

运行:

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值