zoukankan      html  css  js  c++  java
  • 快乐数问题

    问题描述:设计一个算法,判断一个数字是否是“快乐数”。快乐数的定义如下:一个正整数,计算出它各位数字的平方和,得到一个新的数字,再对这个新的数字重复这一过程,直到最后得到数字1或是其他某几个数字的无限循环。在这些数字中,经过上述流程最终能得到数字1的数字,被称为“快乐数”。

    分析:整个算法的设计分为两步

                         第一步:求数下一个平方计算后的数。

                         第二步:判断数值是否是快乐数。

             解法一:分两步进行,第一步计算下一个数,第二步做判断,可以利用一个容器保存计算过的数,只要出现1就直接返回是,如果出现重复的非1的数,就直接返回不是,其他情况继续。

    import java.util.HashSet;
    public class Solution {
        
        public boolean isHappy(int n) {
            
            int temp = n;
            HashSet<Integer> hashSet = new HashSet<Integer>(); 
            hashSet.add(temp);
            while (true) {
                temp = getNext(temp);
                if (temp == 1) {
                    return true;
                } else if (hashSet.contains(temp)) {
                    return false;
                }
                hashSet.add(temp);
            }
        }
        
        private int getNext(int num) {
            int result = 0;
            while (num > 0) {
                result += (num % 10) * (num % 10);
                num = num / 10;
            }
            return result;
        }
    }
    

      解法二:在解法一的基础上进行优化,根据快乐数的性质,如果一个数“不快乐”,则它计算到后面必然陷入到这个循环里:4, 16, 37, 58, 89, 145, 42, 20, 4,

    对于一个大于243的数字来说,它的下一个数字一定比它小。这是因为一个大于1000的数字,它的下一个数字一定比它小,而对于1000以下最大的数字999,它的下一个数字是243,所以1000以下数字的下一个数字也只可能小于或等于243

    基于这两个特征,我们可以设计出下面这个计算效率更高的算法:

    public class Solution {
        
        /**
         * 快乐数的判断
         */
        public boolean isHappy(int n) {
            
            int temp = n;
            while (true) {
                temp = getNext(temp);
                if (temp > 243) {
                    continue;
                } else if (temp == 4 || temp == 16 || temp == 37 || temp == 58 ||
                    temp == 89 || temp == 145 || temp == 42 || temp == 20) {
                    return false;
                } else if (temp == 1) {
                    return true;
                }
            }
        }
        
        /**
         * 获取下一个快乐的数
         */
        private int getNext(int num) {
            int result = 0;
            while (num > 0) {
                result += (num % 10) * (num % 10);
                num = num / 10;
            }
            return result;
        }
    }
    

      

  • 相关阅读:
    RTOS双向链表数据结构
    [LintCode] Majority Number(以时间复杂度O(n)求主元素)
    [LintCode] Median(期望时间复杂度O(n)求中位数和第k大数)
    [LintCode]unique paths with obstacles
    [LintCode]unique paths
    [LintCode]sqrt(x)
    排序算法(C++实现)
    优先队列C++实现
    散列之分离链接法
    AVL树C++实现
  • 原文地址:https://www.cnblogs.com/guozhenqiang/p/5672376.html
Copyright © 2011-2022 走看看