Sum of Perfect Square Elements in Array: C, C++, Java, Python
Find the sum of perfect square elements in an array in C, C++, Java, and Python. Algorithm, floating-point safety, traced example, and complexity analysis.
For the array {1, 2, 3, 4, 5, 9}, the sum of its perfect square elements is 14.
The three qualifying elements are 1, 4, and 9. Numbers like 2, 3, and 5 are skipped. This filter-and-accumulate pattern is one of the most consistently tested array problems in placement coding rounds: TCS NQT, AMCAT Automata, and technical screening rounds at mid-size IT firms all use variants of it. One pass through the array is all you need.
What Is a Perfect Square?
A square number is a non-negative integer that equals the product of some integer multiplied by itself. The first several: 0 (0 × 0), 1 (1 × 1), 4 (2 × 2), 9 (3 × 3), 16 (4 × 4), 25 (5 × 5), 36, 49, 64, 81, 100.
Two edge cases matter for code correctness:
- Zero: 0 =
0 × 0, so 0 is a valid perfect square. A guard written asif (n <= 0) return falseincorrectly excludes it. Writeif (n < 0) return falseinstead. - Negatives: No negative integer is a perfect square. Any real number squared is non-negative, so a negative input should exit the check immediately.
Algorithm Step-by-Step
- Read the array and its length.
- Initialise
sum = 0. - For each element
numin the array:- Compute
sq = (int)sqrt(num). - If
sq * sq == numor(sq + 1) * (sq + 1) == num, addnumtosum.
- Compute
- Return
sum.
The (sq + 1) guard in Step 3 is not redundant. On certain compilers, sqrt(9) returns 2.9999... rather than exactly 3.0. Casting to int gives 2, and 2 * 2 = 4 does not equal 9. The guard catches this floating-point truncation with one extra multiplication and no branching.
Worked Example
Input: {1, 2, 3, 4, 5, 9}
- Element 1:
sq = 1.1 * 1 = 1equals 1. Perfect square. sum = 1. - Element 2:
sq = 1.1 * 1 = 1,2 * 2 = 4. Neither equals 2. Skip. sum = 1. - Element 3:
sq = 1.1 * 1 = 1,2 * 2 = 4. Neither equals 3. Skip. sum = 1. - Element 4:
sq = 2.2 * 2 = 4equals 4. Perfect square. sum = 5. - Element 5:
sq = 2.2 * 2 = 4,3 * 3 = 9. Neither equals 5. Skip. sum = 5. - Element 9:
sq = 3(or 2 if float-truncated). Guard:(2+1) * (2+1) = 9. Perfect square. sum = 14. - Output: 14
How to Test Whether a Number Is a Perfect Square
Two approaches appear in placement solutions. Both produce identical results; they differ in whether you use the standard math library.
Method 1: sqrt and square-back
int isPerfectSquare(int n) {
if (n < 0) return 0;
int sq = (int)sqrt((double)n);
return sq * sq == n || (sq + 1) * (sq + 1) == n;
}
This runs in O(1) time per element. The (double) cast prevents integer overflow inside sqrt for large inputs. The (sq + 1) guard handles the floating-point rounding described in the algorithm section above.
Method 2: brute-force loop (no math library)
int isPerfectSquare(int n) {
if (n < 0) return 0;
for (int i = 0; (long long)i * i <= n; i++) {
if (i * i == n) return 1;
}
return 0;
}
This runs in O(√n) time per element but requires no math.h. For array elements up to a few million, the brute-force version is fast enough on any placement judge. Both approaches pass the same test cases.
The GeeksforGeeks walkthrough on checking perfect squares in C++ covers both variants with additional notes on integer overflow for large inputs.
Complete Programs
C
#include <stdio.h>
#include <math.h>
int isPerfectSquare(int n) {
if (n < 0) return 0;
int sq = (int)sqrt((double)n);
return sq * sq == n || (sq + 1) * (sq + 1) == n;
}
int sumPerfectSquares(int arr[], int size) {
int sum = 0;
for (int i = 0; i < size; i++) {
if (isPerfectSquare(arr[i]))
sum += arr[i];
}
return sum;
}
int main() {
int arr[] = {1, 2, 3, 4, 5, 9};
int size = sizeof(arr) / sizeof(arr[0]);
printf("Sum of perfect square elements: %d\n", sumPerfectSquares(arr, size));
return 0;
}
Output: Sum of perfect square elements: 14
C++
#include <iostream>
#include <cmath>
#include <vector>
using namespace std;
bool isPerfectSquare(int n) {
if (n < 0) return false;
int sq = (int)sqrt((double)n);
return sq * sq == n || (sq + 1) * (sq + 1) == n;
}
int sumPerfectSquares(const vector<int>& arr) {
int sum = 0;
for (int x : arr) {
if (isPerfectSquare(x))
sum += x;
}
return sum;
}
int main() {
vector<int> arr = {1, 2, 3, 4, 5, 9};
cout << "Sum of perfect square elements: " << sumPerfectSquares(arr) << endl;
return 0;
}
Output: Sum of perfect square elements: 14
Java
public class PerfectSquareSum {
static boolean isPerfectSquare(int n) {
if (n < 0) return false;
int sq = (int) Math.sqrt(n);
return sq * sq == n || (sq + 1) * (sq + 1) == n;
}
static int sumPerfectSquares(int[] arr) {
int sum = 0;
for (int x : arr) {
if (isPerfectSquare(x))
sum += x;
}
return sum;
}
public static void main(String[] args) {
int[] arr = {1, 2, 3, 4, 5, 9};
System.out.println("Sum of perfect square elements: " + sumPerfectSquares(arr));
}
}
Output: Sum of perfect square elements: 14
Python
import math
def is_perfect_square(n):
if n < 0:
return False
sq = int(math.sqrt(n))
return sq * sq == n or (sq + 1) * (sq + 1) == n
def sum_perfect_squares(arr):
return sum(x for x in arr if is_perfect_square(x))
arr = [1, 2, 3, 4, 5, 9]
print("Sum of perfect square elements:", sum_perfect_squares(arr))
Output: Sum of perfect square elements: 14
Python’s int(math.sqrt(n)) truncates toward zero, same as C. The (sq + 1) guard becomes more relevant for large integers where float precision degrades.
Complexity Analysis
| Metric | Method 1 (sqrt) | Method 2 (brute-force) |
|---|---|---|
| Time per element | O(1) | O(√M), M = max element |
| Time for full array | O(n) | O(n × √M) |
| Auxiliary space | O(1) | O(1) |
Both methods use O(1) auxiliary space: just one integer variable (sum) that does not grow with input size. No additional array or structure is allocated.
The loop structure here is the same pattern described in sum of digits of a number: initialise an accumulator, test a property of each element with arithmetic, add or skip. The symmetric pairs problem adds a HashMap layer on top of the same traversal skeleton when the test requires looking across elements rather than at a single element.
The (sq + 1) guard catches the case where sqrt(9) returns 2.999 at the cost of one extra multiplication. That same category of silent precision error appears in ML pipelines, where off-by-epsilon gaps in feature computation produce wrong predictions without a crash. TinkerLLM is a hands-on platform for exploring LLM integration and data pipeline experiments through real API calls, starting at ₹299.
Primary sources
Frequently asked questions
What is a perfect square in mathematics?
A perfect square is a non-negative integer that equals the square of another integer. The sequence starts: 0 (0x0), 1 (1x1), 4 (2x2), 9 (3x3), 16 (4x4), 25 (5x5). Any integer n is a perfect square if some integer k satisfies k times k equals n.
Does 0 count as a perfect square?
Yes. Zero equals 0 times 0, so it satisfies the definition. A guard written as `if (n <= 0) return false` incorrectly excludes it. The correct guard is `if (n < 0) return false`.
Why does the program add a (sq+1) check after computing sqrt(n)?
The `sqrt` function returns a floating-point result. On some compilers and platforms, `sqrt(9)` can return `2.9999...` instead of `3.0`. Casting to int gives 2, and `2 times 2 = 4`, which does not equal 9. The `(sq+1)` check tests whether the next integer squared equals n, catching this truncation error at the cost of one multiplication.
What if none of the array elements is a perfect square?
The function returns 0. The `sum` variable is initialised to 0 and never incremented when no element passes the test, so 0 is the correct identity element for addition over an empty qualifying set.
What is the time complexity of this algorithm?
O(n), where n is the length of the array. Each element takes O(1) to test using the sqrt approach (one sqrt call, two multiplications, two comparisons). The loop runs once per element. Auxiliary space is O(1): just the `sum` variable.
Can this program handle negative numbers in the array?
Yes, with the `if (n < 0) return 0` guard at the start of `isPerfectSquare`. Without it, passing a negative to `sqrt` produces NaN in C/C++ or a domain error in Java's `Math.sqrt`, giving wrong results. The guard exits immediately for any negative input.
A self-paced playground for building with LLMs.
TinkerLLM is FACE Prep's sister property. A guided environment for shipping real LLM applications, the kind of project that earns a paragraph on your resume, not a line.
Try TinkerLLM (₹299 launch)