Welcome to Subscribe On Youtube
3265. Count Almost Equal Pairs I
Description
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
ory
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:
- 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 <= 100
1 <= nums[i] <= 106
Solutions
Solution 1: Sorting + Enumeration
We can enumerate each number, and for each number, we can enumerate each pair of different digits, then swap these two digits to get a new number. We record this new number in a hash table $s$, representing all possible numbers after at most one swap. Then, we count how many numbers previously enumerated are in the hash table $s$ and add this count to the answer. Next, we add the currently enumerated number to the hash table $\textit{cnt}$, representing the count of the current number.
This enumeration method may miss some pairs, such as $[100, 1]$, because the number obtained by swapping digits in $100$ is $1$, and previously enumerated numbers do not include $1$, thus missing some pairs. We can solve this problem by sorting the array before enumeration.
The time complexity is $O(n \times (\log n + \log^3 M))$, and the space complexity is $O(n + \log^2 M)$. Here, $n$ is the length of the array $\textit{nums}$, and $M$ is the maximum value in the array $\textit{nums}$.
-
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; } }
-
class Solution { public: int countPairs(vector<int>& nums) { sort(nums.begin(), nums.end()); int ans = 0; unordered_map<int, int> cnt; for (int x : nums) { unordered_set<int> vis = {x}; string s = to_string(x); for (int j = 0; j < s.length(); ++j) { for (int i = 0; i < j; ++i) { swap(s[i], s[j]); vis.insert(stoi(s)); swap(s[i], s[j]); } } for (int y : vis) { ans += cnt[y]; } cnt[x]++; } return ans; } };
-
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
-
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 }
-
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; }