Count Nice Pairs in Dart — Modular Arithmetic Trick

· 5 min read

⚡ TL;DR

Count nice pairs in an array in Dart. Learn the modular arithmetic trick that turns O(n²) into O(n) using hash maps, with full code and tests.

Nice Pairs (#1814) is a clever problem where the naive approach fails for large inputs. The trick is a mathematical transformation that lets you solve it in O(n) time with a hash map. In this Dart-focused guide, we solve it step by step.

Problem Statement

Given an array nums of integers, a pair (i, j) is called nice if i < j and:

Copy
nums[i] + rev(nums[j]) == rev(nums[i]) + nums[j]

Count the number of nice pairs. rev(x) reverses the digits of x (e.g., rev(123) = 321).

Example:

Copy
Input: nums = [42, 11, 1, 97]
Output: 2
Explanation: Pairs (0,3) and (1,2) are nice.
- 42 + rev(97) = 42 + 79 = 121
- rev(42) + 97 = 24 + 97 = 121
- 11 + rev(1) = 11 + 1 = 12
- rev(11) + 1 = 11 + 1 = 12

The Key Insight

Subtract both sides:

Copy
nums[i] + rev(nums[j]) == rev(nums[i]) + nums[j]
nums[i] - rev(nums[i]) == nums[j] - rev(nums[j])

So we just count how many numbers have the same value of nums[i] - rev(nums[i]).


Approach 1: Brute Force (O(n²))

Check every pair (i, j) where i < j.

Copy
int countNicePairsBrute(List<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 (nums[i] + rev(nums[j]) == rev(nums[i]) + nums[j]) {
        count++;
      }
    }
  }
  return count;
}

int rev(int x) {
  int res = 0;
  while (x != 0) {
    res = res * 10 + x % 10;
    x ~/= 10;
  }
  return res;
}

void main() {
  print(countNicePairsBrute([42, 11, 1, 97])); // 2
}

Time: O(n²)
Space: O(1)
Verdict: Works but fails for n = 10⁵ (too slow).


Approach 2: Hash Map + Trick (O(n))

Compute nums[i] - rev(nums[i]) for each element and count occurrences using a hash map.

Copy
int rev(int x) {
  int r = 0;
  while (x > 0) {
    r = r * 10 + x % 10;
    x ~/= 10;
  }
  return r;
}

int countNicePairsHash(List<int> nums) {
  int mod = 1000000007;
  Map<int, int> freq = {};
  int count = 0;

  for (int i = 0; i < nums.length; i++) {
    int val = nums[i] - rev(nums[i]);
    val = ((val % mod) + mod) % mod; // Handle negatives
    int occurrences = freq[val] ?? 0;
    count = (count + occurrences) % mod;
    freq[val] = occurrences + 1;
  }

  return count;
}

void main() {
  print(countNicePairsHash([42, 11, 1, 97])); // 2
}

How it works:

  • For each new element, check how many previous elements had the same nums[i] - rev(nums[i]) value
  • Each occurrence contributes one new nice pair
  • Modular arithmetic prevents overflow (mod 10⁹ + 7)

Time: O(n) — single pass
Space: O(n) — hash map stores all differences


Dart-Specific Implementation Notes

Using Map<int, int> with ?? operator:

Copy
int value = freq[key] ?? 0; // null-coalescing operator

Modular arithmetic in Dart needs extra care for negatives:

Copy
int modVal = ((x % mod) + mod) % mod; // ensures positive mod

Comparison Table

ApproachTimeSpaceInterview Use
Brute ForceO(n²)O(1)Never — fails for large n
Hash MapO(n)O(n)✅ Always use

Test Cases

Copy
void main() {
  assert(countNicePairsHash([42, 11, 1, 97]) == 2);
  assert(countNicePairsHash([13, 10, 35, 24, 76]) == 4);
  assert(countNicePairsHash([]) == 0);
  assert(countNicePairsHash([1]) == 0);
  assert(countNicePairsHash([1, 1]) == 1);
  print("All tests passed!");
}

Explanation for [13, 10, 35, 24, 76]:

  • 13 - rev(13) = 13 - 31 = -18
  • 10 - rev(10) = 10 - 1 = 9
  • 35 - rev(35) = 35 - 53 = -18
  • 24 - rev(24) = 24 - 42 = -18
  • 76 - rev(76) = 76 - 67 = 9

Pairs with same value: (-18): (0,2), (0,3), (2,3) => 3 pairs. (9): (1,4) => 1 pair. Total 4 pairs.


Edge Cases

  1. Empty array → return 0
  2. One element → return 0
  3. All same values → n choose 2 pairs
  4. All unique values → 0 pairs
  5. Negative results → handle with proper mod arithmetic in Dart

Practice Variations

  1. Count pairs with equal sum (nums[i] + nums[j])
  2. Count pairs where XOR is 0 (nice pairs for XOR)
  3. Count pairs where difference equals k

The hash map + linear scan pattern appears in many LeetCode problems. Master it!

FAQ

What is the best approach to solve Count Nice Pairs in Dart?

The recommended approach is the optimal approach, which runs in O(n²) time with O(1) space. The full Dart implementation is shown above.

What is the time complexity of Count Nice Pairs in Dart?

Using the optimal approach, the time complexity is O(n²) and the space complexity is O(1).

Related Recommended Services
Visual Studio Code for the Web

Visual Studio Code for the Web

Build with Visual Studio Code, anywhere, anytime, in your browser.

IDEVISUAL STUDIOVISUAL STUDIO CODEWEB
Renovate | Automated Dependency Updates

Renovate | Automated Dependency Updates

Renovate Bot keeps source code dependencies up-to-date using automated Pull Requests.

AUTOMATED DEPENDENCY UPDATESBUNDLERCOMPOSERGITHUBGO MODULES
Best XML Formatter and XML Beautifier

Best XML Formatter and XML Beautifier

Online XML Formatter will format xml data, helps to validate, and works as XML Converter. Save and Share XML.

XMLXML BEAUTIFIERXML CONVERTERXML FORMATXML FORMATTER
Kubecost | Kubernetes cost monitoring and management

Kubecost | Kubernetes cost monitoring and management

Kubecost started in early 2019 as an open-source tool to give developers visibility into Kubernetes spend. We maintain a deep commitment to building and supporting dedicated solutions for the open source community.

CLOUDKUBECOSTKUBERNETESOPEN SOURCESELF HOSTED
Related Recommended Stories
How GitHub reduced testing time for iOS apps with new runner features

How GitHub reduced testing time for iOS apps with new runner features

Learn how GitHub used macOS and Apple Silicon runners for GitHub Actions to build, test, and deploy our iOS app faster.

IOSGITHUBTESTINGRUNNER
5 ways to transform your workflow using GitHub Copilot and MCP

5 ways to transform your workflow using GitHub Copilot and MCP

Learn how to streamline your development workflow with five different MCP use cases.

AGENT MODECODING AGENTCOPILOTFIGMAGITHUB
One weird trick for powerful Git aliases

One weird trick for powerful Git aliases

Advanced Git Aliases

ALIASALIAS TEMPLATEATLASSIANBITBUCKETGIT
Awesome Python

Awesome Python

An opinionated list of awesome Python frameworks, libraries, software and resources

AWESOMEAWESOME PYTHONCOLLECTIONSGITHUBPYTHON
Related Recommended Tools
Find out what websites are built with - Wappalyzer

Find out what websites are built with - Wappalyzer

Find out the technology stack of any website. Create lists of websites and contacts by the technologies they use.

ADD ONSANALYTICSAPP STOREAPPLEBOOKING
Sourcetree | Free Git GUI for Mac and Windows

Sourcetree | Free Git GUI for Mac and Windows

A Git GUI that offers a visual representation of your repositories. Sourcetree is a free Git client for Windows and Mac.

GITGITHUBGITLABATLASSIANBITBUCKET
Related Recommended Videos