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 an array nums that consists of non-negative integers. Let us define rev(x) as the reverse of the non-negative integer x. For example, rev(123) = 321, and rev(120) = 21. A pair of indices (i, j) is nice if it satisfies all of the following conditions:
0 <= i < j < nums.lengthnums[i] + rev(nums[j]) == nums[j] + rev(nums[i])Return the number of nice pairs of indices. Since that number can be too large, return it modulo 109 + 7.
Example 1:
Input: nums = [42,11,1,97] Output: 2 Explanation: The two pairs are: - (0,3) : 42 + rev(97) = 42 + 79 = 121, 97 + rev(42) = 97 + 24 = 121. - (1,2) : 11 + rev(1) = 11 + 1 = 12, 1 + rev(11) = 1 + 11 = 12.
Example 2:
Input: nums = [13,10,35,24,76] Output: 4
Constraints:
1 <= nums.length <= 1050 <= nums[i] <= 109Problem summary: You are given an array nums that consists of non-negative integers. Let us define rev(x) as the reverse of the non-negative integer x. For example, rev(123) = 321, and rev(120) = 21. A pair of indices (i, j) is nice if it satisfies all of the following conditions: 0 <= i < j < nums.length nums[i] + rev(nums[j]) == nums[j] + rev(nums[i]) Return the number of nice pairs of indices. Since that number can be too large, return it modulo 109 + 7.
Start with the most direct exhaustive search. That gives a correctness anchor before optimizing.
Pattern signal: Array · Hash Map · Math
[42,11,1,97]
[13,10,35,24,76]
number-of-pairs-of-interchangeable-rectangles)count-number-of-bad-pairs)number-of-pairs-satisfying-inequality)Source-backed implementations are provided below for direct study and interview prep.
// Accepted solution for LeetCode #1814: Count Nice Pairs in an Array
class Solution {
public int countNicePairs(int[] nums) {
Map<Integer, Integer> cnt = new HashMap<>();
for (int x : nums) {
int y = x - rev(x);
cnt.merge(y, 1, Integer::sum);
}
final int mod = (int) 1e9 + 7;
long ans = 0;
for (int v : cnt.values()) {
ans = (ans + (long) v * (v - 1) / 2) % mod;
}
return (int) ans;
}
private int rev(int x) {
int y = 0;
for (; x > 0; x /= 10) {
y = y * 10 + x % 10;
}
return y;
}
}
// Accepted solution for LeetCode #1814: Count Nice Pairs in an Array
func countNicePairs(nums []int) (ans int) {
rev := func(x int) (y int) {
for ; x > 0; x /= 10 {
y = y*10 + x%10
}
return
}
cnt := map[int]int{}
for _, x := range nums {
y := x - rev(x)
cnt[y]++
}
const mod int = 1e9 + 7
for _, v := range cnt {
ans = (ans + v*(v-1)/2) % mod
}
return
}
# Accepted solution for LeetCode #1814: Count Nice Pairs in an Array
class Solution:
def countNicePairs(self, nums: List[int]) -> int:
def rev(x):
y = 0
while x:
y = y * 10 + x % 10
x //= 10
return y
cnt = Counter(x - rev(x) for x in nums)
mod = 10**9 + 7
return sum(v * (v - 1) // 2 for v in cnt.values()) % mod
// Accepted solution for LeetCode #1814: Count Nice Pairs in an Array
struct Solution;
use std::collections::HashMap;
const MOD: i64 = 1_000_000_007;
impl Solution {
fn count_nice_pairs(nums: Vec<i32>) -> i32 {
let mut hm: HashMap<i32, i32> = HashMap::new();
let mut res: i64 = 0;
for x in nums {
let diff = x - rev(x);
let count = hm.entry(diff).or_default();
res += *count as i64;
*count += 1;
}
(res % MOD) as i32
}
}
fn rev(mut x: i32) -> i32 {
let mut digits: Vec<i32> = vec![];
while x > 0 {
digits.push(x % 10);
x /= 10;
}
let mut res = 0;
for x in digits {
res *= 10;
res += x;
}
res
}
#[test]
fn test() {
let nums = vec![42, 11, 1, 97];
let res = 2;
assert_eq!(Solution::count_nice_pairs(nums), res);
let nums = vec![13, 10, 35, 24, 76];
let res = 4;
assert_eq!(Solution::count_nice_pairs(nums), res);
}
// Accepted solution for LeetCode #1814: Count Nice Pairs in an Array
function countNicePairs(nums: number[]): number {
const rev = (x: number): number => {
let y = 0;
while (x) {
y = y * 10 + (x % 10);
x = Math.floor(x / 10);
}
return y;
};
const mod = 10 ** 9 + 7;
const cnt = new Map<number, number>();
let ans = 0;
for (const x of nums) {
const y = x - rev(x);
ans = (ans + (cnt.get(y) ?? 0)) % mod;
cnt.set(y, (cnt.get(y) ?? 0) + 1);
}
return ans;
}
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: Zero-count keys stay in map and break distinct/count constraints.
Usually fails on: Window/map size checks are consistently off by one.
Fix: Delete keys when count reaches zero.
Wrong move: Temporary multiplications exceed integer bounds.
Usually fails on: Large inputs wrap around unexpectedly.
Fix: Use wider types, modular arithmetic, or rearranged operations.