leetcode202_快乐数_简单_258. 各位相加_简单_263. 丑数_简单

总结

  • 三题知识点

  • 取出一个数的所有个位数,while(num > 0) { int d = num % 10; num = num / 10;}

  • 一个数num包含某个因数factor,则num % factor == 0 ; 若全部是由这个因数组成,则num不断去 / factor, 最后得到的数为1。

  • 若一个数不包含某个因数,则num % factor != 0

  • 涉及思想

  • 定义一个计算法则,即一个映射,这个映射也可以看成一个指针;

  • 如果从一个数开始,经过计算法则出现无限数字无限循环,相当于链表出现了环

  • 链表中,查找环,快慢指针

题目 202_快乐数 简单

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

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

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

示例:

输入:19
输出:true
解释:
1^2 + 9^2 = 82
8^2 + 2^2 = 68
6^2 + 8^2 = 100
1^2 + 0^2 + 0^2 = 1

思路

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
图片地址

  • 怎么判断是不是无限循环

    • 转换为:每个数字都会根据平方和指向另一个数字,从任意数字开始进行各位平方和的迭代操作,就相当于在链表上游走。如果无线循环但始终变不到1,就说明链表走到了环。

    • 为什么呢?为什么无线循环就一定是走到了环呢?而不是链表上的数字越来越大?

    • 不会有一个一直增长的链表

    • 循环链表,用快慢指针破解

      // 怎么判断是不是无限循环,即什么情况下会无限循环
      // 如果数的平方和指向下一个数 ——> 数的平方和指向下一个数 ——> 形成环
      // 形成环就会无限循环
      // 链表的next:在这里是数平方和指向下一个数
      // 环用快慢双指针判断
      // 如果相等,跳出循环,则跳出循环,肯定不是快乐数
      // 如果中途slow == 1, 也跳出循环,是快乐数
      // 1 也会造成循环,如果不在1初判断是否等于1,所以不加判断是否等于1,反正快慢指针会在1出相遇,跳出循环,判断是否等于1就好。

  • 三种情况:

    • 数的平方和有1的情况,且没有除1以外的环
    • 数的平方和没有1,有环
    • 数越来越大,无限大(经证明,数最后 不可能接近无限大)
  • 反正1也会造成环,即slow 会和fast相遇,退出循环,最后判断是不是1就好了

class Solution {
    public boolean isHappy(int n) {
        int slow = n, fast = getNext(n);
        while(slow != fast) {
            slow = getNext(slow);
            fast = getNext(getNext(fast));
        }

        return slow == 1;
    }

 	private int getNext(int num) {
        int sum = 0;
        while(num > 0) {
            int d = num % 10;
            sum += d * d;
            num = num / 10;
        }

        return sum;
    }
}
  • 我碰到1的时候就跳出循环,最后判断是1跳出的循环还是其他循环造成的快慢指针相等跳出的循环。
class Solution {
    public boolean isHappy(int n) {
        int slow = n, fast = getNext(n);
        while(slow != 1 && slow != fast) {
            slow = getNext(slow);
            fast = getNext(getNext(fast));
        }

        return slow == 1;
    }

	 private int getNext(int num) {
        int sum = 0;
        while(num > 0) {
            int d = num % 10;
            sum += d * d;
            num = num / 10;
        }

        return sum;
    }
}

258. 各位相加

给定一个非负整数 num,反复将各个位上的数字相加,直到结果为一位数。

示例:

输入: 38
输出: 2
解释: 各位相加的过程为:3 + 8 = 11, 1 + 1 = 2。 由于 2 是一位数,所以返回 2。

class Solution {
    public int addDigits(int num) {
        // 结束条件 num < 10
        int currNum = num;
        while(currNum >= 10) {
            currNum = getNext(currNum);
        }

        return currNum;
    }

    private int getNext(int num) {
        int sum = 0;
        while(num > 0) {
            int d = num % 10;
            sum += d;
            num = num / 10;
        }

        return sum;
    }
}

263. 丑数_简单

编写一个程序判断给定的数是否为丑数。

丑数就是只包含质因数 2, 3, 5 的正整数。

示例 1:

输入: 6
输出: true
解释: 6 = 2 × 3
示例 2:

输入: 8
输出: true
解释: 8 = 2 × 2 × 2
示例 3:

输入: 14
输出: false
解释: 14 不是丑数,因为它包含了另外一个质因数 7。

思路

  • 如果一个数是丑数,则一定满足:num = 2 ^ i * 3 ^ j * 5 ^ k,
  • 用2, 3, 5不断去除,如果是丑数,则最后肯定是 num = 1 * (2 or 3 or 5) / (2 or 3 or 5) == 1, 1 % (2 or 3 or 5) != 0 跳出循环
  • 结束条件:
    • 2, 3, 5都被除过了,for() 保证2, 3, 5一定都会除
    • 剩下的除数 如果是1 ,即 1 % (2 or 3 or 5) == 1 则是丑数
    • 剩下的除数 如果不是1,即 14 % (2 or 3 or 5) = 2 * 7 + 0 ; 7 % (2 or 3 or 5) = 7 , 则不是丑数;
class Solution {
    public boolean isUgly(int num) {

        if(num <= 0) return false;

        int[] factors = new int[]{2, 3, 5};

        for(int factor : factors) {
            while(num % factor == 0) {
                num = num / factor;
            }
        }

        return num == 1;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值