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 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:

  • 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;
    }
    
    

All Problems

All Solutions