1925. Count Square Sum Triples
Problem Description
A square triple (a, b, c)
is a triple of integers where a² + b² = c²
. This is essentially a Pythagorean triple - three numbers that satisfy the Pythagorean theorem.
Given an integer n
, you need to find and return the total count of all square triples (a, b, c)
where each of a
, b
, and c
are integers between 1 and n
inclusive.
For example, if n = 5
, the triple (3, 4, 5)
would be valid because 3² + 4² = 9 + 16 = 25 = 5²
, and all three numbers are within the range [1, 5]
. Similarly, (4, 3, 5)
would also be valid and counted separately.
The solution iterates through all possible values of a
and b
from 1 to n-1
, calculates c
as the square root of a² + b²
, and checks if c
is a perfect square (integer) and within the allowed range. Each valid triple found increments the counter.
Intuition
The key insight is recognizing that we need to find all Pythagorean triples within a bounded range. Since we're looking for triples (a, b, c)
where a² + b² = c²
, we can use a brute force approach given the constraint that all values must be at most n
.
The natural approach is to try all possible combinations of a
and b
, then check if they form a valid triple. For each pair (a, b)
, we can directly calculate what c
should be using the formula c = √(a² + b²)
.
Why does this work? Because if a valid triple exists, c
is uniquely determined by a
and b
. We don't need to try all possible values of c
separately - we can compute it directly and then verify two conditions:
- Is
c
an integer? (meaning√(a² + b²)
is a perfect square) - Is
c ≤ n
? (meaning it's within our allowed range)
The check for whether c
is an integer is done by computing c = int(sqrt(x))
where x = a² + b²
, then verifying that c² == x
. If c
were not an integer, then int(sqrt(x))
would truncate the decimal part, and squaring it back wouldn't give us the original x
.
Note that we enumerate a
and b
from 1 to n-1
(not including n
) because even if a = n
or b = n
, the resulting c
would be strictly greater than n
(since c² = a² + b² > a²
when b > 0
), violating our constraint.
Learn more about Math patterns.
Solution Approach
The implementation uses a nested loop enumeration approach to find all valid square triples:
- Outer loop: Iterate
a
from 1 ton-1
- Inner loop: For each
a
, iterateb
from 1 ton-1
- Calculate potential c: For each pair
(a, b)
, computex = a * a + b * b
which representsa² + b²
- Extract integer square root: Calculate
c = int(sqrt(x))
to get the integer part of the square root - Validate the triple: Check two conditions:
c <= n
: Ensuresc
is within the allowed rangec * c == x
: Verifies thatc
is indeed the exact square root ofx
(not truncated)
- Count valid triples: If both conditions are met, increment the answer counter by 1
The algorithm systematically checks all possible combinations of a
and b
values. For each combination, it determines if a valid c
exists that satisfies the Pythagorean theorem within the given constraints.
Time Complexity: O(n²)
as we have two nested loops each running approximately n
times.
Space Complexity: O(1)
as we only use a constant amount of extra space for variables.
The key insight in the implementation is that we don't need to enumerate c
separately. By calculating c
directly from a
and b
, we reduce what would be an O(n³)
brute force approach to an O(n²)
solution.
Ready to land your dream job?
Unlock your dream job with a 5-minute evaluator for a personalized learning plan!
Start EvaluatorExample Walkthrough
Let's walk through the algorithm with n = 5
to find all square triples.
Step 1: Initialize
- Set
answer = 0
- We'll check all pairs
(a, b)
wherea
andb
range from 1 to 4
Step 2: Iterate through all combinations
When a = 1
:
b = 1
:x = 1² + 1² = 2
,c = int(√2) = 1
, check:1² = 1 ≠ 2
❌b = 2
:x = 1² + 2² = 5
,c = int(√5) = 2
, check:2² = 4 ≠ 5
❌b = 3
:x = 1² + 3² = 10
,c = int(√10) = 3
, check:3² = 9 ≠ 10
❌b = 4
:x = 1² + 4² = 17
,c = int(√17) = 4
, check:4² = 16 ≠ 17
❌
When a = 2
:
b = 1
:x = 2² + 1² = 5
,c = int(√5) = 2
, check:2² = 4 ≠ 5
❌b = 2
:x = 2² + 2² = 8
,c = int(√8) = 2
, check:2² = 4 ≠ 8
❌b = 3
:x = 2² + 3² = 13
,c = int(√13) = 3
, check:3² = 9 ≠ 13
❌b = 4
:x = 2² + 4² = 20
,c = int(√20) = 4
, check:4² = 16 ≠ 20
❌
When a = 3
:
b = 1
:x = 3² + 1² = 10
,c = int(√10) = 3
, check:3² = 9 ≠ 10
❌b = 2
:x = 3² + 2² = 13
,c = int(√13) = 3
, check:3² = 9 ≠ 13
❌b = 3
:x = 3² + 3² = 18
,c = int(√18) = 4
, check:4² = 16 ≠ 18
❌b = 4
:x = 3² + 4² = 25
,c = int(√25) = 5
- Check 1:
c = 5 ≤ n = 5
✓ - Check 2:
5² = 25 = x
✓ - Valid triple found!
(3, 4, 5)
,answer = 1
- Check 1:
When a = 4
:
b = 1
:x = 4² + 1² = 17
,c = int(√17) = 4
, check:4² = 16 ≠ 17
❌b = 2
:x = 4² + 2² = 20
,c = int(√20) = 4
, check:4² = 16 ≠ 20
❌b = 3
:x = 4² + 3² = 25
,c = int(√25) = 5
- Check 1:
c = 5 ≤ n = 5
✓ - Check 2:
5² = 25 = x
✓ - Valid triple found!
(4, 3, 5)
,answer = 2
- Check 1:
b = 4
:x = 4² + 4² = 32
,c = int(√32) = 5
, check:5² = 25 ≠ 32
❌
Step 3: Return result
- Total valid square triples found: 2
- The triples are
(3, 4, 5)
and(4, 3, 5)
This example demonstrates how the algorithm efficiently finds Pythagorean triples by:
- Systematically checking all
(a, b)
pairs - Computing the required
c
value directly - Validating that
c
is both an integer and within bounds - Counting each valid triple separately (even if they're permutations like
(3,4,5)
and(4,3,5)
)
Solution Implementation
1import math
2
3class Solution:
4 def countTriples(self, n: int) -> int:
5 """
6 Count the number of Pythagorean triples (a, b, c) where:
7 - a^2 + b^2 = c^2
8 - 1 <= a, b, c <= n
9
10 Args:
11 n: The upper bound for all values in the triple
12
13 Returns:
14 The count of valid Pythagorean triples
15 """
16 count = 0
17
18 # Iterate through all possible values for 'a'
19 for a in range(1, n):
20 # Iterate through all possible values for 'b'
21 for b in range(1, n):
22 # Calculate the sum of squares
23 sum_of_squares = a * a + b * b
24
25 # Find the integer square root (potential value of 'c')
26 c = int(math.sqrt(sum_of_squares))
27
28 # Check if c is within bounds and forms a perfect square
29 # (c^2 == a^2 + b^2)
30 if c <= n and c * c == sum_of_squares:
31 count += 1
32
33 return count
34
1class Solution {
2 /**
3 * Counts the number of Pythagorean triples (a, b, c) where:
4 * - 1 <= a, b, c <= n
5 * - a^2 + b^2 = c^2
6 *
7 * @param n The upper bound for all values in the triple
8 * @return The count of valid Pythagorean triples
9 */
10 public int countTriples(int n) {
11 int tripleCount = 0;
12
13 // Iterate through all possible values for 'a'
14 for (int a = 1; a < n; a++) {
15 // Iterate through all possible values for 'b'
16 for (int b = 1; b < n; b++) {
17 // Calculate the sum of squares: a^2 + b^2
18 int sumOfSquares = a * a + b * b;
19
20 // Calculate the potential value of 'c' using square root
21 int c = (int) Math.sqrt(sumOfSquares);
22
23 // Check if 'c' is within bounds and forms a perfect square
24 // (c^2 == sumOfSquares ensures it's a Pythagorean triple)
25 if (c <= n && c * c == sumOfSquares) {
26 tripleCount++;
27 }
28 }
29 }
30
31 return tripleCount;
32 }
33}
34
1class Solution {
2public:
3 /**
4 * Count the number of Pythagorean triples (a, b, c) where:
5 * - 1 <= a, b, c <= n
6 * - a^2 + b^2 = c^2
7 *
8 * @param n The upper bound for triple values
9 * @return The count of valid Pythagorean triples
10 */
11 int countTriples(int n) {
12 int count = 0;
13
14 // Iterate through all possible values of 'a'
15 for (int a = 1; a < n; ++a) {
16 // Iterate through all possible values of 'b'
17 for (int b = 1; b < n; ++b) {
18 // Calculate the sum of squares
19 int sumOfSquares = a * a + b * b;
20
21 // Find the integer square root (potential value of 'c')
22 int c = static_cast<int>(sqrt(sumOfSquares));
23
24 // Check if 'c' is within bounds and forms a perfect square
25 // (i.e., c^2 equals sumOfSquares, confirming it's a Pythagorean triple)
26 if (c <= n && c * c == sumOfSquares) {
27 ++count;
28 }
29 }
30 }
31
32 return count;
33 }
34};
35
1/**
2 * Counts the number of Pythagorean triples (a, b, c) where:
3 * - a^2 + b^2 = c^2
4 * - 1 <= a, b, c <= n
5 *
6 * @param n - The upper bound for all values in the triple
7 * @returns The count of valid Pythagorean triples
8 */
9function countTriples(n: number): number {
10 let count: number = 0;
11
12 // Iterate through all possible values for 'a'
13 for (let a: number = 1; a < n; a++) {
14 // Iterate through all possible values for 'b'
15 for (let b: number = 1; b < n; b++) {
16 // Calculate the sum of squares: a^2 + b^2
17 const sumOfSquares: number = a * a + b * b;
18
19 // Find the integer square root (potential value for 'c')
20 const c: number = Math.floor(Math.sqrt(sumOfSquares));
21
22 // Check if 'c' is within bounds and forms a perfect square
23 // (i.e., c^2 equals a^2 + b^2)
24 if (c <= n && c * c === sumOfSquares) {
25 count++;
26 }
27 }
28 }
29
30 return count;
31}
32
Time and Space Complexity
The time complexity is O(n^2)
, where n
is the given integer. This is because we have two nested loops, each iterating from 1 to n-1, resulting in approximately n * n
iterations. Within each iteration, we perform constant time operations: calculating a * a + b * b
, computing the square root, and checking if c * c == x
, all of which are O(1)
operations.
The space complexity is O(1)
. The algorithm only uses a fixed amount of extra space for variables ans
, a
, b
, x
, and c
, regardless of the input size n
. No additional data structures that grow with the input size are created.
Learn more about how to find time and space complexity quickly.
Common Pitfalls
1. Floating-Point Precision Issues
The most critical pitfall in this solution is relying on floating-point arithmetic for checking perfect squares. Using int(math.sqrt(sum_of_squares))
can lead to incorrect results due to floating-point precision errors.
Problem Example:
# For large values, sqrt might return something like 4.999999999999
# which truncates to 4 instead of 5
sum_of_squares = 25
c = int(math.sqrt(sum_of_squares)) # Might get 4 instead of 5 due to precision
Solution: Avoid floating-point operations entirely by using integer arithmetic:
def countTriples(self, n: int) -> int:
count = 0
# Pre-compute squares for O(1) lookup
squares = {i * i for i in range(1, n + 1)}
for a in range(1, n):
for b in range(1, n):
sum_of_squares = a * a + b * b
# Check if sum_of_squares is a perfect square and within range
if sum_of_squares in squares:
count += 1
return count
2. Inefficient Range Boundaries
The current solution iterates a
and b
from 1 to n-1
, but this misses valid triples where a
or b
equals n
.
Problem:
# If n = 5, the loop misses checking (5, 0, 5) type cases
# Though (5, 0, 5) isn't valid since b must be >= 1
# But it does miss cases like when a or b could be n
for a in range(1, n): # Goes up to n-1, not n
Solution:
for a in range(1, n + 1): # Include n in the range
for b in range(1, n + 1):
3. Redundant Computation
Computing a * a
repeatedly in the inner loop is inefficient.
Problem:
for a in range(1, n):
for b in range(1, n):
sum_of_squares = a * a + b * b # a*a computed n times unnecessarily
Solution:
for a in range(1, n + 1):
a_squared = a * a # Compute once per outer loop
for b in range(1, n + 1):
sum_of_squares = a_squared + b * b
4. Missing Early Termination Optimization
The solution continues checking even when it's impossible to find valid triples.
Problem:
When a * a + b * b > n * n
, no valid c
can exist, but the loop continues.
Solution:
for a in range(1, n + 1):
a_squared = a * a
if a_squared + 1 > n * n: # Minimum b is 1
break
for b in range(1, n + 1):
sum_of_squares = a_squared + b * b
if sum_of_squares > n * n: # c would exceed n
break
# Check for valid triple
What data structure does Breadth-first search typically uses to store intermediate states?
Recommended Readings
Math for Technical Interviews How much math do I need to know for technical interviews The short answer is about high school level math Computer science is often associated with math and some universities even place their computer science department under the math faculty However the reality is that you
Coding Interview Patterns Your Personal Dijkstra's Algorithm to Landing Your Dream Job The goal of AlgoMonster is to help you get a job in the shortest amount of time possible in a data driven way We compiled datasets of tech interview problems and broke them down by patterns This way
Recursion Recursion is one of the most important concepts in computer science Simply speaking recursion is the process of a function calling itself Using a real life analogy imagine a scenario where you invite your friends to lunch https assets algo monster recursion jpg You first call Ben and ask
Want a Structured Path to Master System Design Too? Don’t Miss This!