力扣202. 快乐数

方法:哈希法

为什么这么想:判断一个正整数是不是快乐数是要每一次将该数替换为它。一直重复,如果它变成1,说明是快乐数,如果它无限循环则不是快乐数。那我们怎么判断它是否无限循环了呢?很简单,就看它经过上面计算后是否与之前计算后的数相同,那就可以理解为快速判断一个元素是否出现集合里,因此用哈希法。接下来我们考虑用数组,set还是map。题目中说了1 <= n <= 2^31 - 1,可见数字太大,不适合数组。map的话要存入两个数据,而我们只需要存一个数据,因此用set。

思路:将一个正整数进行每个位置上的数字的平方和的计算,如果为1,返回true,不为1,看这个值之前是否存在,不存在添加到set,存在说明进入循环,返回false。

//改进前代码:两层while循环,时间复杂度高
class Solution {
    public boolean isHappy(int n) {
     ArrayList<Integer> list=new ArrayList<>();
     HashSet<Integer> sumSet=new HashSet<>();
       int n1=0;
       int sum=0;
       while(true)
       {
         //把n的每一位存入list集合
         while(n!=0)
         {
            n1=n%10;
            list.add(n1);
            n=n/10;
         }
         //遍历list,求每个位置上的数字的平方和
         for(int c:list)
            sum=sum+c*c;
            //清除list上的元素
            list.clear();
            //sum为1,是快乐数
            if(sum==1)
              return true;
              //sum不为1
              else
              {
                  //set包含sum,说明无限循环,不是快乐数
                  if(sumSet.contains(sum))
                    return false;
                    //不包含
                    else
                    {
                     //sum存入set
                      sumSet.add(sum);
                      //改变n值
                      n=sum;
                      sum=0;
                    }
              }
       }
    }
}

改进:再写一个方法专门处理每个位置上的数字平方和,这样就不会有两层while循环了。

//改进后代码
class Solution {
    public boolean isHappy(int n) {
        HashSet<Integer> sumSet=new HashSet<>();
       int sum=0;
       while(true)
       {    //调用方法
            sum=sumSquares(n);
            //sum为1,是快乐数
            if(sum==1)
              return true;
              //不为1
              else
              {
                  //进入循环,不是快乐数
                  if(sumSet.contains(sum))
                    return false;
                    //没有进入循环
                    else
                    {
                      //存入set
                      sumSet.add(sum);
                      //改变n的值
                      n=sum;
                    }
              }
       }
    }
    //计算n的每个位置上的数字的平方和
    public int sumSquares(int n)
    {
        int sum=0;
        int n1=0;
         while(n!=0)
         {
            n1=n%10;
            sum=sum+n1*n1;
            n=n/10;
         }
            return sum;
    }
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值