Mathematics
Number Theory
Perfect Square
Integer Range
Math Puzzles

Does a range of integers contain at least one perfect square?

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

To decide whether an integer interval contains a perfect square, you do not need to scan every number. The problem reduces to checking whether some integer k satisfies k^2 between the lower and upper bounds, which can be done directly with square roots or integer square-root operations.

The Core Test

Suppose the range is [a, b] with a <= b. The range contains at least one perfect square if and only if:

text
ceil(sqrt(a)) <= floor(sqrt(b))

Why? Because:

  • 'ceil(sqrt(a)) is the smallest integer whose square is at least a'
  • 'floor(sqrt(b)) is the largest integer whose square is at most b'

If the first number is no larger than the second, then at least one integer square lies in the interval.

For example, in [20, 30]:

  • 'ceil(sqrt(20)) = 5'
  • 'floor(sqrt(30)) = 5'

Since 5 <= 5, the interval contains the perfect square 25.

A Simple Python Implementation

Python's math.isqrt is ideal because it avoids floating-point edge cases.

python
1import math
2
3def contains_perfect_square(a: int, b: int) -> bool:
4    if a > b:
5        raise ValueError("a must be <= b")
6
7    if b < 0:
8        return False
9
10    a = max(a, 0)
11    lower = math.isqrt(a)
12    if lower * lower < a:
13        lower += 1
14
15    upper = math.isqrt(b)
16    return lower <= upper
17
18
19print(contains_perfect_square(20, 30))   # True, because 25 is inside
20print(contains_perfect_square(26, 35))   # False
21print(contains_perfect_square(-5, 2))    # True, because 0 and 1 are inside

This runs in constant time relative to the interval length. That is much better than checking every number in the range.

Finding the Square, Not Just the Answer

If you also want to know which perfect square appears first, return the candidate square directly:

python
1import math
2
3def first_perfect_square(a: int, b: int):
4    if a > b:
5        raise ValueError("a must be <= b")
6    if b < 0:
7        return None
8
9    a = max(a, 0)
10    k = math.isqrt(a)
11    if k * k < a:
12        k += 1
13
14    square = k * k
15    return square if square <= b else None
16
17
18print(first_perfect_square(20, 30))  # 25
19print(first_perfect_square(26, 35))  # None

This is useful in search or interval-processing problems where you need the actual square, not only a yes-or-no answer.

Why Scanning the Range Is Wasteful

A naive method would test every integer from a to b and check whether it is a perfect square. That is unnecessary for large intervals.

For example, if the range spans millions of numbers, the direct square-root method still takes essentially the same amount of time because it computes only a handful of arithmetic operations.

This makes the problem a good example of turning an apparent search problem into a simple arithmetic condition.

Common Pitfalls

The biggest mistake is using floating-point square roots carelessly for very large integers. Floating-point rounding can produce off-by-one errors near square boundaries. Integer square-root functions are safer.

Another issue is forgetting about negative lower bounds. Negative integers are not perfect squares over the integers, but the interval may still contain 0 or a positive square if the upper bound is nonnegative.

Developers also sometimes assume every interval of length at least n must contain a square. That is false unless you reason carefully about gaps between consecutive squares, which grow as the numbers get larger.

Finally, do not loop through the entire range unless the interval is tiny and simplicity matters more than performance.

Summary

  • An interval [a, b] contains a perfect square if ceil(sqrt(a)) <= floor(sqrt(b)).
  • Integer square-root operations are safer than floating-point checks.
  • The test can be done in constant time relative to the size of the interval.
  • Negative lower bounds need special handling, but the arithmetic stays simple.
  • You can return the first square in the interval just as easily as returning a boolean.

Course illustration
Course illustration

All Rights Reserved.