標籤:
1、題目名稱
Happy Number(快樂數)
2、題目地址
https://leetcode.com/problems/happy-number/
3、題目內容
英文:
Write an algorithm to determine if a number is "happy".
A happy number is a number defined by the following process: Starting with any positive integer, replace the number by the sum of the squares of its digits, and repeat the process until the number equals 1 (where it will stay), or it loops endlessly in a cycle which does not include 1. Those numbers for which this process ends in 1 are happy numbers.
中文:
設計一個演算法,判斷一個數字是否“快樂”。快樂數可以被如下流程定義:一個正整數,計算出它各位元字的平方和,得到一個新的數字,再對這個新的數字重複這一過程,直到最後得到數字1或是其他某幾個數位無限迴圈。在這些數字中,經過上述流程最終能得到數字1的數字,被稱為“快樂數”。
4、解題方法
根據題目中對快樂數的定義,可以設計下面的Java代碼:
import java.util.LinkedList;/** * @功能說明:LeetCode 202 - Happy Number * @開發人員:Tsybius2014 * @開發時間:2015年11月1日 */public class Solution { /** * 快樂的數 * @param n * @return */ public boolean isHappy(int n) { long num = new Long(n); long temp = num; LinkedList<Long> linkedList = new LinkedList<Long>(); linkedList.add(temp); while (true) { temp = getNext(temp); if (temp == 1L) { return true; } else if (linkedList.contains(temp)) { return false; } linkedList.add(temp); } } /** * 擷取下一個快樂的數 * @param num * @return */ private Long getNext(long num) { long result = 0L; while (num > 0) { result += (num % 10L) * (num % 10L); num = num / 10L; } return result; }}
這段代碼中,使用鏈表(LinkedList)記錄已經找到的數字,如果某一個產生的數字在之前的計算中曾經出現過且不為1,則說明這個數字不是快樂數,如果某一個產生的數字為1,則說明這個數字一定是快樂數。除了鏈表外,還可以使用HashSet記錄已經找到的數字:
import java.util.HashSet;/** * @功能說明:LeetCode 202 - Happy Number * @開發人員:Tsybius2014 * @開發時間:2015年11月1日 */public class Solution { /** * 快樂的數 * @param n * @return */ public boolean isHappy(int n) { long num = new Long(n); long temp = num; HashSet<Long> hashSet = new HashSet<Long>(); hashSet.add(temp); while (true) { temp = getNext(temp); if (temp == 1L) { return true; } else if (hashSet.contains(temp)) { return false; } hashSet.add(temp); } } /** * 擷取下一個快樂的數 * @param num * @return */ private Long getNext(long num) { long result = 0L; while (num > 0) { result += (num % 10L) * (num % 10L); num = num / 10L; } return result; }}
5、解題方法的改進
如果要對上面的解題方法進行改進,我們需要進一步瞭解快樂數的性質。
為此我查閱了維基百科上關於快樂數的描述: https://en.wikipedia.org/wiki/Happy_number
發現快樂數有如下特徵:
1、如果一個數“不快樂”,則它計算到後面必然陷入到這個迴圈裡:4, 16, 37, 58, 89, 145, 42, 20, 4, ...
2、對於一個大於243的數字來說,它的下一個數字一定比它小。這是因為一個大於1000的數字,它的下一個數字一定比它小,而對於1000以下最大的數字999,它的下一個數字是243,所以1000以下數位下一個數字也只可能小於或等於243
基於這兩個特徵,我們可以設計出下面這個計算效率更高的演算法:
/** * @功能說明:LeetCode 202 - Happy Number * @開發人員:Tsybius2014 * @開發時間:2015年11月1日 */public class Solution { /** * 快樂的數 * @param n * @return */ public boolean isHappy(int n) { long num = new Long(n); long temp = num; while (true) { temp = getNext(temp); if (temp > 243L) { continue; } else if (temp == 4L || temp == 16L || temp == 37L || temp == 58L || temp == 89L || temp == 145L || temp == 42L || temp == 20L) { return false; } else if (temp == 1L) { return true; } } } /** * 擷取下一個快樂的數 * @param num * @return */ private Long getNext(long num) { long result = 0L; while (num > 0) { result += (num % 10L) * (num % 10L); num = num / 10L; } return result; }}
END
LeetCode:Happy Number - 快樂數