Count Almost Equal Pairs I
MedPrompt
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
xoryand 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:
- 3 and 30. By swapping 3 and 0 in 30, you get 3.
- 12 and 21. By swapping 1 and 2 in 12, you get 21.
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] <= 106
Approaches
2 approaches with complexity analysis and trade-offs.
This straightforward approach involves checking every possible pair of numbers in the array to see if they are almost equal.
Algorithm
- Initialize a counter
countto 0. - Use a nested loop to iterate through every pair of indices
(i, j)such thati < j. - For each pair, call a helper function
isAlmostEqual(nums[i], nums[j]). - If the helper function returns
true, incrementcount. - After checking all pairs, return
count.
Helper isAlmostEqual(x, y):
- Convert
xandyto stringss1ands2. - If their lengths are different, return
false. - Find all indices where
s1ands2differ. - If there are 0 differing indices, they are equal, return
true. - If there are 2 differing indices, say
d1andd2, check ifs1[d1] == s2[d2]ands1[d2] == s2[d1]. If true, returntrue. - Otherwise, return
false.
Walkthrough
The algorithm uses two nested loops to iterate through all unique pairs of indices (i, j) where i < j. For each pair of numbers (nums[i], nums[j]), a helper function isAlmostEqual is invoked. This function determines if one number can be transformed into the other by at most one swap of digits. It does this by converting the numbers to strings and comparing them. If the strings are identical (zero swaps), they are almost equal. If they differ, the function counts the number of positions with different characters. If there are exactly two differing positions, it verifies if these characters are swapped between the two strings. If this condition holds, the pair is considered almost equal (one swap). A counter is incremented for every almost equal pair found.
class Solution { public int countAlmostEqualPairs(int[] nums) { int n = nums.length; int count = 0; for (int i = 0; i < n; i++) { for (int j = i + 1; j < n; j++) { if (isAlmostEqual(nums[i], nums[j])) { count++; } } } return count; } private boolean isAlmostEqual(int x, int y) { String s1 = String.valueOf(x); String s2 = String.valueOf(y); if (s1.length() != s2.length()) { return false; } java.util.List<Integer> diffIndices = new java.util.ArrayList<>(); for (int i = 0; i < s1.length(); i++) { if (s1.charAt(i) != s2.charAt(i)) { diffIndices.add(i); } } if (diffIndices.isEmpty()) { return true; // The numbers are equal } if (diffIndices.size() == 2) { int i = diffIndices.get(0); int j = diffIndices.get(1); return s1.charAt(i) == s2.charAt(j) && s1.charAt(j) == s2.charAt(i); } return false; }}Complexity
Time
O(N^2 * D), where N is the length of the `nums` array and D is the maximum number of digits in a number. The two nested loops result in O(N^2) pairs. For each pair, the `isAlmostEqual` function takes O(D) time for string conversion and comparison.
Space
O(D), where D is the maximum number of digits. This space is used by the helper function to store the indices of differing characters.
Trade-offs
Pros
Simple to understand and implement.
Works well for the given constraints due to the small size of N.
Cons
Inefficient for larger input sizes as its time complexity is quadratic.
Solutions
Solution
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; }}Video walkthrough
Newsletter
One sharp idea, every week
System design and interview prep — short enough to finish.
No spam. Unsubscribe anytime.
Practice
Same difficulty — related problems to reinforce the pattern.