Off-by-one on range boundaries
Wrong move: Loop endpoints miss first/last candidate.
Usually fails on: Fails on minimal arrays and exact-boundary answers.
Fix: Re-derive loops from inclusive/exclusive ranges before coding.
Move from brute-force thinking to an efficient approach using array strategy.
You are given 2 positive integers l and r. For any number x, all positive divisors of x except x are called the proper divisors of x.
A number is called special if it has exactly 2 proper divisors. For example:
Return the count of numbers in the range [l, r] that are not special.
Example 1:
Input: l = 5, r = 7
Output: 3
Explanation:
There are no special numbers in the range [5, 7].
Example 2:
Input: l = 4, r = 16
Output: 11
Explanation:
The special numbers in the range [4, 16] are 4 and 9.
Constraints:
1 <= l <= r <= 109Problem summary: You are given 2 positive integers l and r. For any number x, all positive divisors of x except x are called the proper divisors of x. A number is called special if it has exactly 2 proper divisors. For example: The number 4 is special because it has proper divisors 1 and 2. The number 6 is not special because it has proper divisors 1, 2, and 3. Return the count of numbers in the range [l, r] that are not special.
Start with the most direct exhaustive search. That gives a correctness anchor before optimizing.
Pattern signal: Array · Math
5 7
4 16
count-primes)Source-backed implementations are provided below for direct study and interview prep.
// Accepted solution for LeetCode #3233: Find the Count of Numbers Which Are Not Special
class Solution {
static int m = 31623;
static boolean[] primes = new boolean[m + 1];
static {
Arrays.fill(primes, true);
primes[0] = primes[1] = false;
for (int i = 2; i <= m; i++) {
if (primes[i]) {
for (int j = i + i; j <= m; j += i) {
primes[j] = false;
}
}
}
}
public int nonSpecialCount(int l, int r) {
int lo = (int) Math.ceil(Math.sqrt(l));
int hi = (int) Math.floor(Math.sqrt(r));
int cnt = 0;
for (int i = lo; i <= hi; i++) {
if (primes[i]) {
cnt++;
}
}
return r - l + 1 - cnt;
}
}
// Accepted solution for LeetCode #3233: Find the Count of Numbers Which Are Not Special
const m = 31623
var primes [m + 1]bool
func init() {
for i := range primes {
primes[i] = true
}
primes[0] = false
primes[1] = false
for i := 2; i <= m; i++ {
if primes[i] {
for j := i * 2; j <= m; j += i {
primes[j] = false
}
}
}
}
func nonSpecialCount(l int, r int) int {
lo := int(math.Ceil(math.Sqrt(float64(l))))
hi := int(math.Floor(math.Sqrt(float64(r))))
cnt := 0
for i := lo; i <= hi; i++ {
if primes[i] {
cnt++
}
}
return r - l + 1 - cnt
}
# Accepted solution for LeetCode #3233: Find the Count of Numbers Which Are Not Special
m = 31623
primes = [True] * (m + 1)
primes[0] = primes[1] = False
for i in range(2, m + 1):
if primes[i]:
for j in range(i + i, m + 1, i):
primes[j] = False
class Solution:
def nonSpecialCount(self, l: int, r: int) -> int:
lo = ceil(sqrt(l))
hi = floor(sqrt(r))
cnt = sum(primes[i] for i in range(lo, hi + 1))
return r - l + 1 - cnt
// Accepted solution for LeetCode #3233: Find the Count of Numbers Which Are Not Special
/**
* [3233] Find the Count of Numbers Which Are Not Special
*/
pub struct Solution {}
// submission codes start here
impl Solution {
pub fn non_special_count(l: i32, r: i32) -> i32 {
let n = (r as f64).sqrt() as usize;
let mut v = vec![true; n + 1];
let mut result = r - l + 1;
let (l, r) = (l as usize, r as usize);
for i in 2..=n {
if v[i] {
if i.pow(2) >= l && i.pow(2) <= r {
result -= 1;
}
for j in ((i * 2)..=n).step_by(i) {
v[j] = false;
}
}
}
result
}
}
// submission codes end
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_3233() {
assert_eq!(19, Solution::non_special_count(5, 25));
assert_eq!(3, Solution::non_special_count(5, 7));
assert_eq!(11, Solution::non_special_count(4, 16));
}
}
// Accepted solution for LeetCode #3233: Find the Count of Numbers Which Are Not Special
const m = 31623;
const primes: boolean[] = Array(m + 1).fill(true);
(() => {
primes[0] = primes[1] = false;
for (let i = 2; i <= m; ++i) {
if (primes[i]) {
for (let j = i * 2; j <= m; j += i) {
primes[j] = false;
}
}
}
})();
function nonSpecialCount(l: number, r: number): number {
const lo = Math.ceil(Math.sqrt(l));
const hi = Math.floor(Math.sqrt(r));
let cnt = 0;
for (let i = lo; i <= hi; ++i) {
if (primes[i]) {
++cnt;
}
}
return r - l + 1 - cnt;
}
Use this to step through a reusable interview workflow for this problem.
Two nested loops check every pair or subarray. The outer loop fixes a starting point, the inner loop extends or searches. For n elements this gives up to n²/2 operations. No extra space, but the quadratic time is prohibitive for large inputs.
Most array problems have an O(n²) brute force (nested loops) and an O(n) optimal (single pass with clever state tracking). The key is identifying what information to maintain as you scan: a running max, a prefix sum, a hash map of seen values, or two pointers.
Review these before coding to avoid predictable interview regressions.
Wrong move: Loop endpoints miss first/last candidate.
Usually fails on: Fails on minimal arrays and exact-boundary answers.
Fix: Re-derive loops from inclusive/exclusive ranges before coding.
Wrong move: Temporary multiplications exceed integer bounds.
Usually fails on: Large inputs wrap around unexpectedly.
Fix: Use wider types, modular arithmetic, or rearranged operations.