题目:

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.

Example: 19 is a happy number

  • 12 + 92 = 82
  • 82 + 22 = 68
  • 62 + 82 = 100
  • 12 + 02 + 02 = 1

链接: http://leetcode.com/problemset/algorithms/

题解:

判断一个数字是否为Happy Number。这道题跟求无限循环小数很像,最好维护一个HashSet,假如遇见重复,则返回false。否则替换n为digits square root sum,当n == 1时循环结束返回true。

Time Complexity - O(n), Space Complexity - O(n)。

public class Solution {
public boolean isHappy(int n) {
if(n <= 0)
return false;
Set<Integer> set = new HashSet<>(); while(n != 1) {
if(set.contains(n))
return false;
else {
set.add(n);
n = getSquareSumOfDigits(n);
}
} return true;
} private int getSquareSumOfDigits(int n) {
int res = 0; while(n > 0) {
res += (n % 10) * (n % 10);
n /= 10;
} return res;
}
}

二刷:

就是在i != 1的情况对n进行处理,使用一个Set来保存出现过的数字,假如重复则出现循环,这时候我们return false。否则跳出循环的时候n == 1,我们return true。

Java:

Time Complexity - O(n), Space Complexity - O(n)。  时间复杂度和空间复杂度需要用数学公式来推算。这公式是什么我现在也不知道。

public class Solution {
public boolean isHappy(int n) {
if (n < 1) {
return false;
}
Set<Integer> set = new HashSet<>();
set.add(n);
int newNum = 0;
while (n != 1) {
while (n != 0) {
newNum += (n % 10) * (n % 10);
n /= 10;
}
if (!set.add(newNum)) {
return false;
}
n = newNum;
newNum = 0;
}
return true;
}
}

题外话: 今天试了一下Coursera的Crytography I,感觉难度比较大,需要很好的概率知识。做作业的时候参考了别人在github上写的Python代码,好简洁。自己也要好好练起来。又发现了几个比较优美的算法课件,都是来自Kevin Wayne,要好好看一看。其实至今为止自己收集了很多资料,包括书籍,课件,Source Code, Video等等,但总觉得没准备好,心里没底,也许是因为这leetcode到现在第一遍还没完成吧。说不定真刷到了5遍7遍的,融会贯通了以后,才会安心一点。

三刷:

Java:

public class Solution {
public boolean isHappy(int n) {
if (n < 1) {
return false;
}
Set<Integer> set = new HashSet<>();
set.add(n);
while (n != 1) {
n = getSquareSum(n);
if (!set.add(n)) {
return false;
}
}
return true;
} private int getSquareSum(int num) {
int res = 0;
while (num != 0) {
int remainder = num % 10;
res += remainder * remainder;
num /= 10;
}
return res;
}
}

Update:

public class Solution {
public boolean isHappy(int n) {
if (n < 1) return false;
Set<Integer> set = new HashSet<>();
while (n != 1) {
int num = 0;
while (n != 0) {
num += (n % 10) * (n % 10);
n /= 10;
}
if (!set.add(num)) return false;
n = num;
}
return true;
}
}

更好的解可以把Space Complexity 简化到 O(1),使用 fast / slow pointer进行Cycle Detection的思路,很巧妙。 更奇妙的是运行时间也减少了。

public class Solution {
public boolean isHappy(int n) {
if (n < 1) {
return false;
}
int x = n, y = getDigitSquareSum(n);
while (x != y) {
x = getDigitSquareSum(x);
y = getDigitSquareSum(getDigitSquareSum(y)); }
return x == 1;
} private int getDigitSquareSum(int n) {
int res = 0;
while (n > 0) {
int curDigit = n % 10;
res += curDigit * curDigit;
n /= 10;
}
return res;
}
}

Update:

public class Solution {
public boolean isHappy(int n) {
if (n < 1) return false;
int slow = n, fast = getSquareSum(n);
while (slow != fast) {
slow = getSquareSum(slow);
fast = getSquareSum(getSquareSum(fast));
}
return slow == 1;
} private int getSquareSum(int n) {
int num = 0;
while (n != 0) {
num += (n % 10) * (n % 10);
n /= 10;
}
return num;
}
}

四刷:

class Solution {
Set<Integer> set = new HashSet<>(); public boolean isHappy(int n) {
if (n < 1) return false;
if (set.contains(n)) return n == 1;
else set.add(n);
return isHappy(getSquareSum(n));
} private int getSquareSum(int n) {
int num = 0;
while (n != 0) {
num += (n % 10) * (n % 10);
n /= 10;
}
return num;
}
}

Reference:

https://leetcode.com/discuss/33055/my-solution-in-c-o-1-space-and-no-magic-math-property-involved

https://leetcode.com/discuss/71625/explanation-those-posted-algorithms-mathematically-valid

https://leetcode.com/discuss/33349/o-1-space-java-solution

http://www.cs.princeton.edu/courses/archive/spring13/cos423/lectures.php

http://www.cs.princeton.edu/courses/archive/fall12/cos226/lectures.php

202. Happy Number的更多相关文章

  1. Leetcode 202 Happy Number 弗洛伊德判环解循环

    今天先谈下弗洛伊德判环,弗洛伊德判环原来是在一个圈内有两人跑步,同时起跑,一人的速度是另一人的两倍,则那个人能在下一圈追上另一个人,弗洛伊德判环能解数字会循环出现的题,比如说判断一个链表是不是循环链表 ...

  2. LeetCode 202 Happy Number

    Problem: Write an algorithm to determine if a number is "happy". A happy number is a numbe ...

  3. leetCode191/201/202/136 -Number of 1 Bits/Bitwise AND of Numbers Range/Happy Number/Single Number

    一:Number of 1 Bits 题目: Write a function that takes an unsigned integer and returns the number of '1' ...

  4. Java for LeetCode 202 Happy Number

    Write an algorithm to determine if a number is "happy". A happy number is a number defined ...

  5. (easy)LeetCode 202.Happy Number

    Write an algorithm to determine if a number is "happy". A happy number is a number defined ...

  6. 【LeetCode】202 - Happy Number

    Write an algorithm to determine if a number is "happy". A happy number is a number defined ...

  7. Java [Leetcode 202]Happy Number

    题目描述: Write an algorithm to determine if a number is "happy". A happy number is a number d ...

  8. LeetCode OJ 202. Happy Number

    Write an algorithm to determine if a number is "happy". A happy number is a number defined ...

  9. 40. leetcode 202. Happy Number

    Write an algorithm to determine if a number is "happy". A happy number is a number defined ...

随机推荐

  1. 查看cpu、内存和硬盘

    查看cpu cat /proc/cpuinfo 查看内存 top free -m 按兆为单位输出内存的已用,未用,总共等结果 cat /proc/meminfo |grep MemTotal 查看硬盘 ...

  2. 写在十年 2007-09-15 (写给L之三)

    你知道吗? 那种时间很远,但心很近的感觉.   时间已经远去了十年, 但亲切的感觉依然清晰可见,   无论时光远去了十年,二十年,三十年, 永远…… 它已经植根,在心间……

  3. item44:将与参数无关的代码抽离template

    编写non-template代码中,重复十分明显:可以很直观的看到代码的重复,然后将它们写成一个新的class或者函数,然后供调用. 编写template代码中,重复是隐晦的:只存在一份templat ...

  4. OCI的结果输出

    绑定变量,把结果以列的方式输出到每一字段输出到一个数组里

  5. JAVA_SE复习(Class)

    一.面向对象程序设计(OOP) 1.面向对象的程序设计是程序开发的一种方法.它将对象作为程序的基本单元,将程序和 数据封装其中,以提高软件的重用性.灵活性和扩展性 2.三个特征: 封装:隐藏信息 继承 ...

  6. MySQL学习笔记之数据存储类型

    说明:本文是作者对MySQL数据库数据存储类型的小小总结. Numeric Type (数字类型) 1.TINYINT.SMALLINT.MEDIUMINT.INT.BIGINT主要根据存储字节长度不 ...

  7. Linux ed

    ed 编辑器是 Linux 操作系统下最简单的文本编辑器.它是以行为单位对文件进行编辑的编辑器,而不像 MS-DOS 系统下的 edit 那样是以整个屏幕框架为单位对文件进行编辑的.因此,如果你已经习 ...

  8. @Html.Partial,@Html.Action,@Html.RenderPartial,@Html.RenderAction区别

    ASP.NET MVC 中@Html.Partial,@Html.Action,@Html.RenderPartial,@Html.RenderAction区别 对这四个的区别做一个总结,清理一下思路 ...

  9. preventDefault()、stopPropagation()、return false 之间的区别

    “return false”之所以被误用的如此厉害,是因为它看起来像是完成了我们交给它的工作,浏览器不会再将我们重定向到href中的链接,表单也不会被继续提交,但这么做到底有什么不对呢? 可能在你刚开 ...

  10. javascript截取字符串(支持中英文混合)

    javascript截取字符串(支持中英文混合) <script type="text/javascript"> var sub=function(str,n){ va ...