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 consisting of positive integers.
We call two integers x and y in this problem almost equal if both integers can become equal after performing the following operation at most once:
x or y and swap any two digits within the chosen number.Return the number of indices i and j in nums where i < j such that nums[i] and nums[j] are almost equal.
Note that it is allowed for an integer to have leading zeros after performing an operation.
Example 1:
Input: nums = [3,12,30,17,21]
Output: 2
Explanation:
The almost equal pairs of elements are:
Example 2:
Input: nums = [1,1,1,1,1]
Output: 10
Explanation:
Every two elements in the array are almost equal.
Example 3:
Input: nums = [123,231]
Output: 0
Explanation:
We cannot swap any two digits of 123 or 231 to reach the other.
Constraints:
2 <= nums.length <= 1001 <= nums[i] <= 106Problem summary: You are given an array nums consisting of positive integers. We call two integers x and y in this problem almost equal if both integers can become equal after performing the following operation at most once: Choose either x or y and swap any two digits within the chosen number. Return the number of indices i and j in nums where i < j such that nums[i] and nums[j] are almost equal. Note that it is allowed for an integer to have leading zeros after performing an operation.
Start with the most direct exhaustive search. That gives a correctness anchor before optimizing.
Pattern signal: Array · Hash Map
[3,12,30,17,21]
[1,1,1,1,1]
[123,231]
check-if-one-string-swap-can-make-strings-equal)Source-backed implementations are provided below for direct study and interview prep.
// Accepted solution for LeetCode #3265: Count Almost Equal Pairs I
class Solution {
public int countPairs(int[] nums) {
Arrays.sort(nums);
int ans = 0;
Map<Integer, Integer> cnt = new HashMap<>();
for (int x : nums) {
Set<Integer> vis = new HashSet<>();
vis.add(x);
char[] s = String.valueOf(x).toCharArray();
for (int j = 0; j < s.length; ++j) {
for (int i = 0; i < j; ++i) {
swap(s, i, j);
vis.add(Integer.parseInt(String.valueOf(s)));
swap(s, i, j);
}
}
for (int y : vis) {
ans += cnt.getOrDefault(y, 0);
}
cnt.merge(x, 1, Integer::sum);
}
return ans;
}
private void swap(char[] s, int i, int j) {
char t = s[i];
s[i] = s[j];
s[j] = t;
}
}
// Accepted solution for LeetCode #3265: Count Almost Equal Pairs I
func countPairs(nums []int) (ans int) {
sort.Ints(nums)
cnt := make(map[int]int)
for _, x := range nums {
vis := make(map[int]struct{})
vis[x] = struct{}{}
s := []rune(strconv.Itoa(x))
for j := 0; j < len(s); j++ {
for i := 0; i < j; i++ {
s[i], s[j] = s[j], s[i]
y, _ := strconv.Atoi(string(s))
vis[y] = struct{}{}
s[i], s[j] = s[j], s[i]
}
}
for y := range vis {
ans += cnt[y]
}
cnt[x]++
}
return
}
# Accepted solution for LeetCode #3265: Count Almost Equal Pairs I
class Solution:
def countPairs(self, nums: List[int]) -> int:
nums.sort()
ans = 0
cnt = defaultdict(int)
for x in nums:
vis = {x}
s = list(str(x))
for j in range(len(s)):
for i in range(j):
s[i], s[j] = s[j], s[i]
vis.add(int("".join(s)))
s[i], s[j] = s[j], s[i]
ans += sum(cnt[x] for x in vis)
cnt[x] += 1
return ans
// Accepted solution for LeetCode #3265: Count Almost Equal Pairs I
// Rust example auto-generated from java reference.
// Replace the signature and local types with the exact LeetCode harness for this problem.
impl Solution {
pub fn rust_example() {
// Port the logic from the reference block below.
}
}
// Reference (java):
// // Accepted solution for LeetCode #3265: Count Almost Equal Pairs I
// class Solution {
// public int countPairs(int[] nums) {
// Arrays.sort(nums);
// int ans = 0;
// Map<Integer, Integer> cnt = new HashMap<>();
// for (int x : nums) {
// Set<Integer> vis = new HashSet<>();
// vis.add(x);
// char[] s = String.valueOf(x).toCharArray();
// for (int j = 0; j < s.length; ++j) {
// for (int i = 0; i < j; ++i) {
// swap(s, i, j);
// vis.add(Integer.parseInt(String.valueOf(s)));
// swap(s, i, j);
// }
// }
// for (int y : vis) {
// ans += cnt.getOrDefault(y, 0);
// }
// cnt.merge(x, 1, Integer::sum);
// }
// return ans;
// }
//
// private void swap(char[] s, int i, int j) {
// char t = s[i];
// s[i] = s[j];
// s[j] = t;
// }
// }
// Accepted solution for LeetCode #3265: Count Almost Equal Pairs I
function countPairs(nums: number[]): number {
nums.sort((a, b) => a - b);
let ans = 0;
const cnt = new Map<number, number>();
for (const x of nums) {
const vis = new Set<number>();
vis.add(x);
const s = x.toString().split('');
for (let j = 0; j < s.length; j++) {
for (let i = 0; i < j; i++) {
[s[i], s[j]] = [s[j], s[i]];
vis.add(+s.join(''));
[s[i], s[j]] = [s[j], s[i]];
}
}
for (const y of vis) {
ans += cnt.get(y) || 0;
}
cnt.set(x, (cnt.get(x) || 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.