Given a positive integer n, generate a sequence by repeatedly replacing the current number with the sum of the squares of its digits. Determine whether this sequence eventually reaches 1. Return true if it does, otherwise return false.
Examples :
Input: n = 19
Output: true
Explanation:
19 = 1² + 9² = 82
82 = 8² + 2² = 68
68 = 6² + 8² = 100
100 = 1² + 0² + 0² = 1
Since the sequence reaches 1, return true.
Input: n = 20
Output: false
Explanation:
20 = 2² + 0² = 4
4 = 4² = 16
16 = 1² + 6² = 37
37 = 3² + 7² = 58
58 = 5² + 8² = 89
89 = 8² + 9² = 145
145 = 1² + 4² + 5² = 42
42 = 4² + 2² = 20
The sequence enters a cycle without reaching 1, so return false.
Table of Content
Simulate the Sequence using Hash Set - O(log n) Time and O(Log n) Space
The idea is to repeatedly replace the current number with the sum of the squares of its digits. While generating the sequence, store every number in a hash set. If the sequence reaches 1, return true. If a number appears again, it means the sequence has entered a cycle and will never reach 1, so return false.
#include <bits/stdc++.h>
using namespace std;
// Returns the sum of squares of digits of n.
int squareSum(int n)
{
int sum = 0;
while (n > 0)
{
int digit = n % 10;
sum += digit * digit;
n /= 10;
}
return sum;
}
bool reachesOne(int n)
{
// Stores previously seen numbers.
unordered_set<int> visited;
while (n != 1 && !visited.count(n))
{
visited.insert(n);
n = squareSum(n);
}
return n == 1;
}
int main()
{
int n = 19;
if (reachesOne(n))
cout << "true";
else
cout << "false";
return 0;
}
import java.util.HashSet;
public class GFG {
// Returns the sum of squares of digits of n.
static int squareSum(int n)
{
int sum = 0;
while (n > 0) {
int digit = n % 10;
sum += digit * digit;
n /= 10;
}
return sum;
}
static boolean reachesOne(int n)
{
// Stores previously seen numbers.
HashSet<Integer> visited = new HashSet<>();
while (n != 1 && !visited.contains(n)) {
visited.add(n);
n = squareSum(n);
}
return n == 1;
}
public static void main(String[] args)
{
int n = 19;
if (reachesOne(n))
System.out.println("true");
else
System.out.println("false");
}
}
def squareSum(n):
# Returns the sum of squares of digits of n.
sum = 0
while n > 0:
digit = n % 10
sum += digit * digit
n //= 10
return sum
def reachesOne(n):
# Stores previously seen numbers.
visited = set()
while n != 1 and n not in visited:
visited.add(n)
n = squareSum(n)
return n == 1
if __name__ == "__main__":
n = 19
if reachesOne(n):
print("true")
else:
print("false")
using System;
using System.Collections.Generic;
public class GFG {
// Returns the sum of squares of digits of n.
public static int squareSum(int n)
{
int sum = 0;
while (n > 0) {
int digit = n % 10;
sum += digit * digit;
n /= 10;
}
return sum;
}
public static bool reachesOne(int n)
{
// Stores previously seen numbers.
HashSet<int> visited = new HashSet<int>();
while (n != 1 && !visited.Contains(n)) {
visited.Add(n);
n = squareSum(n);
}
return n == 1;
}
public static void Main()
{
int n = 19;
if (reachesOne(n))
Console.WriteLine("true");
else
Console.WriteLine("false");
}
}
function squareSum(n)
{
// Returns the sum of squares of digits of n.
let sum = 0;
while (n > 0) {
let digit = n % 10;
sum += digit * digit;
n = Math.floor(n / 10);
}
return sum;
}
function reachesOne(n)
{
// Stores previously seen numbers.
let visited = new Set();
while (n != 1 && !visited.has(n)) {
visited.add(n);
n = squareSum(n);
}
return n == 1;
}
let n = 19;
if (reachesOne(n)) {
console.log("true");
}
else {
console.log("false");
}
Output
true
Floyd's Cycle Detection - O(log n) Time and O(1) Space
We use Floyd's Cycle Detection (Tortoise and Hare) algorithm, where one pointer moves one step at a time and the other moves two steps at a time. If they meet before reaching 1, a cycle exists and the answer is false.
Let us understand with example:
Input: n = 19
Initialize slow = 19 and fast = 19.
Iteration 1:
- slow = nextNum(19) = 82
- fast = nextNum(nextNum(19)) = nextNum(82) = 68
- slow != fast, so continue.
Iteration 2:
- slow = nextNum(82) = 68
- fast = nextNum(nextNum(68)) = nextNum(100) = 1
- slow != fast, so continue.
Iteration 3:
- slow = nextNum(68) = 100
- fast = nextNum(nextNum(1)) = nextNum(1) = 1
- slow != fast, so continue.
Iteration 4:
- slow = nextNum(100) = 1
- fast = nextNum(nextNum(1)) = 1
- Now slow == fast == 1, so the loop stops and the function returns true.
#include <bits/stdc++.h>
using namespace std;
int nextNum(int n)
{
int sum = 0;
// Compute the sum of squares of digits.
while (n > 0)
{
int d = n % 10;
sum += d * d;
n /= 10;
}
return sum;
}
bool reachesOne(int n)
{
int slow = n;
int fast = n;
// Detect a cycle using Floyd's cycle-finding algorithm.
do
{
slow = nextNum(slow);
fast = nextNum(nextNum(fast));
} while (slow != fast);
// The sequence reaches 1 iff the detected cycle contains 1.
return slow == 1;
}
int main()
{
int n = 19;
if (reachesOne(n))
cout << "true";
else
cout << "false";
return 0;
}
public class GFG {
public static int nextNum(int n)
{
int sum = 0;
// Compute the sum of squares of digits.
while (n > 0) {
int d = n % 10;
sum += d * d;
n /= 10;
}
return sum;
}
public static boolean reachesOne(int n)
{
int slow = n;
int fast = n;
// Detect a cycle using Floyd's cycle-finding
// algorithm.
do {
slow = nextNum(slow);
fast = nextNum(nextNum(fast));
} while (slow != fast);
// The sequence reaches 1 iff the detected cycle
// contains 1.
return slow == 1;
}
public static void main(String[] args)
{
int n = 19;
if (reachesOne(n))
System.out.println("true");
else
System.out.println("false");
}
}
def nextNum(n):
sum = 0
# Compute the sum of squares of digits.
while n > 0:
d = n % 10
sum += d * d
n //= 10
return sum
def reachesOne(n):
slow = n
fast = n
# Detect a cycle using Floyd's cycle-finding algorithm.
while True:
slow = nextNum(slow)
fast = nextNum(nextNum(fast))
if slow == fast:
break
# The sequence reaches 1 iff the detected cycle contains 1.
return slow == 1
if __name__ == "__main__":
n = 19
if reachesOne(n):
print("true")
else:
print("false")
using System;
public class GFG {
public static int nextNum(int n)
{
int sum = 0;
// Compute the sum of squares of digits.
while (n > 0) {
int d = n % 10;
sum += d * d;
n /= 10;
}
return sum;
}
public static bool reachesOne(int n)
{
int slow = n;
int fast = n;
// Detect a cycle using Floyd's cycle-finding
// algorithm.
do {
slow = nextNum(slow);
fast = nextNum(nextNum(fast));
} while (slow != fast);
// The sequence reaches 1 iff the detected cycle
// contains 1.
return slow == 1;
}
public static void Main()
{
int n = 19;
if (reachesOne(n))
Console.WriteLine("true");
else
Console.WriteLine("false");
}
}
function nextNum(n)
{
let sum = 0;
// Compute the sum of squares of digits.
while (n > 0) {
let d = n % 10;
sum += d * d;
n = Math.floor(n / 10);
}
return sum;
}
function reachesOne(n)
{
let slow = n;
let fast = n;
// Detect a cycle using Floyd's cycle-finding algorithm.
do {
slow = nextNum(slow);
fast = nextNum(nextNum(fast));
} while (slow != fast);
// The sequence reaches 1 iff the detected cycle
// contains 1.
return slow == 1;
}
let n = 19;
if (reachesOne(n)) {
console.log("true");
}
else {
console.log("false");
}
Output
true