Problem Statement
Given an integer N. The task is to determine if N is a Happy Number.
A Happy number is a number defined by the following process:
- Start with any positive integer, and replace the number with the sum of the squares of its digits.
- Repeat the process until the number equals 1, or it loops endlessly in a cycle which does not include 1.
- Those numbers for which this process ends in 1 are happy numbers.
Examples:
- Input: N = 97
- Output: True
Explanation:
Input: N = 2
Output: False
Approach 1: Cycle Detection using HashSet
Let us understand this approach with an example.
Let us dry run the following:
- N = 7
- Squaring, N = 49. Now, N = 4^2 + 9 ^ 2 = 97.
- N = 9^2 + 7^2 = 130
- N = 1^2 + 3^2 + 0^2 = 10
- N = 1^0 + 0^2 = 1
So, N becomes 1, hence, 7 is a happy number.
Let us take another example, where the number remains in a loop.
In the above example, it can be clearly observed that, after a few steps, the loops remains in a loop and can never reach 1, hence 116 is not a happy number.
Algorithm:
- Initialise a hashset to determine whether an integer has occurred previously or not.
- Initialise an integer with N and the next integer generated would be the sum of squares of digits of the current integer.
- Repeat the above process, until N reaches 1 or a number which has previously occurred again appears, i.e. enters into a cycle.
- Return True if N reaches 1, else return False.
C++ Code
int getNext(int n) { int totalSum = 0; while (n > 0) { int d = n % 10; n = n / 10; totalSum += d * d; } return totalSum; } bool isHappy(int n) { set<int> seen; while (n != 1 && seen.find(n) == seen.end()) { seen.insert(n); n = getNext(n); } return n == 1; }
Java Code
private int getNext(int n) { int totalSum = 0; while (n > 0) { int d = n % 10; n = n / 10; totalSum += d * d; } return totalSum; } public boolean isHappy(int n) { Set<Integer> seen = new HashSet<>(); while (n != 1 && !seen.contains(n)) { seen.add(n); n = getNext(n); } return n == 1; }
Python Code
def get_next(n): total_sum = 0 while n > 0: n, digit = divmod(n, 10) total_sum += digit ** 2 return total_sum seen = set() while n != 1 and n not in seen: seen.add(n) n = get_next(n) return n == 1
Time Complexity: O(logN)
Space Complexity: O(N), since HashSet is used.
Approach 2: Floyd’s Cycle Detection Algorithm
If an integer is not a Happy number, after certain steps it gets into the cycle. Now, this cycle can be thought of as a linked list and then our task would be to simply detect if a cycle exists in a linked list.
Floyd’s Cycle Detection Algorithm is based on two-pointers- fast and slow pointers. The slow pointer moves ahead by one step at a time, whereas the fast pointer moves ahead by two steps at a time. In case, there is a cycle, both the fast and slow pointer eventually meet after at a certain point.
Algorithm:
- Initialise slow pointer with N and fast pointer with the sum of squares of digits of N.
- While fast pointer doesn’t become equal to 1 and slow and fast pointer doesn’t meet,
- Replace slow with the sum of squares of digits of slow.
- Replace fast with the sum of squares of digits of fast.
- Return True if fast becomes 1, else return False.
C++ Implementation
int getNext(int n) { int totalSum = 0; while (n > 0) { int d = n % 10; n = n / 10; totalSum += d * d; } return totalSum; } bool isHappy(int n) { int slowRunner = n; int fastRunner = getNext(n); while (fastRunner != 1 && slowRunner != fastRunner) { slowRunner = getNext(slowRunner); fastRunner = getNext(getNext(fastRunner)); } return fastRunner == 1; } }
Java Implementation
public int getNext(int n) { int totalSum = 0; while (n > 0) { int d = n % 10; n = n / 10; totalSum += d * d; } return totalSum; } public boolean isHappy(int n) { int slowRunner = n; int fastRunner = getNext(n); while (fastRunner != 1 && slowRunner != fastRunner) { slowRunner = getNext(slowRunner); fastRunner = getNext(getNext(fastRunner)); } return fastRunner == 1; } }
Python Implementation
def get_next(number): total_sum = 0 while number > 0: number, digit = divmod(number, 10) total_sum += digit ** 2 return total_sum slow_runner = n fast_runner = get_next(n) while fast_runner != 1 and slow_runner != fast_runner: slow_runner = get_next(slow_runner) fast_runner = get_next(get_next(fast_runner)) return fast_runner == 1
- Time Complexity: O(logN)
- Space Complexity: O(1)
Practice Question
FAQ
Q.1: How do you handle the case, if the integer goes on increasing till infinity?
Ans: You do not need to explicitly handle this case, since any number until a 32-bit integer would remain in a cycle of 1053(The sum of squares of digits of 9999999999999 is 1053).
Q.2: What is Floyd’s cycle detection algorithm?
Ans: Floyd’s Cycle Detection Algorithm is based on two-pointers- fast and slow pointers. The slow pointer moves ahead by one step at a time, whereas the fast pointer moves ahead by two steps at a time. In case, there is a cycle, both the fast and slow pointers eventually meet at a certain point.