My Solution
\n/**\n * Time Complexity: O(n * log(n) + n * (log(max_num) ^ 4))\n * Space Complexity: O(n_characters)\n * where `n` is the length of the vector `nums`\n *    
```\n/**\n * Time Complexity: O(n * log(n) + n * (log(max_num) ^ 4))\n * Space Complexity: O(n_characters)\n * where `n` is the length of the vector `nums`\n *       `max_num` is the maximum number of the vector `nums`\n *       `n_characters` is the number of the characters\n *                         of the string representations\n *                         of all numbers of the vector `nums`\n */\nclass Solution {\n private:\n  class Item {\n   public:\n    Item(const int num) : num_(num), s_num_(to_string(num)) {\n    }\n    \n    bool operator<(const Item &rhs) const noexcept {\n      return s_num_.size() < rhs.s_num_.size() || (s_num_.size() == rhs.s_num_.size() && num_ < rhs.num_);\n    }\n    \n    bool operator==(const Item &rhs) const noexcept {\n      return num_ == rhs.num_;\n    }\n    \n    int num() const {\n      return num_;\n    }\n    \n    string s_num() const {\n      return s_num_;\n    }\n    \n    int length() const {\n      return static_cast<int>(s_num_.size());\n    }\n    \n   private:\n    int num_;\n    string s_num_;\n  };\n  \n public:\n  int countPairs(const vector<int> &nums) {\n    constexpr int base = 10;\n\n    const int n = static_cast<int>(nums.size());\n    map<Item, int> data;\n    for (int i = 0; i < n; ++i) {\n      ++data[Item(nums[i])];\n    }\n    \n    const int max_length = data.rbegin()->first.length();\n    int power10[max_length];\n    power10[0] = 1;\n    for (int i = 1; i < max_length; ++i) {\n      power10[i] = power10[i - 1] * base;\n    }\n    \n    unordered_map<int, int> num_to_count;\n    int ret = 0;\n    for (const auto &[item, count] : data) {\n      ret += (count * (count - 1)) >> 1;\n      unordered_set<int> seen({item.num()});\n      string s_num(item.s_num());\n      for (int i = 0; i < item.length() - 1; ++i) {\n        for (int j = i + 1; j < item.length(); ++j) {\n          const int swapped1 = item.num() +\n                               (s_num[j] - s_num[i]) * power10[item.length() - i - 1] +\n                               (s_num[i] - s_num[j]) * power10[item.length() - j - 1];\n          do_count(swapped1, num_to_count, count, seen, ret);\n          swap(s_num[i], s_num[j]);\n          for (int k = i + 1; k < item.length() - 1; ++k) {\n            for (int l = k + 1; l < item.length(); ++l) {\n              const int swapped2 = swapped1 +\n                                   (s_num[l] - s_num[k]) * power10[item.length() - k - 1] +\n                                   (s_num[k] - s_num[l]) * power10[item.length() - l - 1];\n              do_count(swapped2, num_to_count, count, seen, ret);\n            }\n          }\n          swap(s_num[i], s_num[j]);\n        }\n      }\n      num_to_count[item.num()] = count;\n    }\n    return ret;\n  }\n  \n private:\n  void do_count(const int swapped,\n                const unordered_map<int, int> &num_to_count,\n                const int count,\n                unordered_set<int> &seen,\n                int &result) {\n    if (seen.find(swapped) != seen.end()) {\n      return;\n    }\n    \n    seen.emplace(swapped);\n    auto itr = num_to_count.find(swapped);\n    result += itr == num_to_count.end() ? 0 : itr->second * count;\n  }\n};\n```
[]