Sum of Imbalance Numbers of All Subarrays

Hard
1800.

Sum of Imbalance Numbers of All Subarrays

Sum of Imbalance Numbers of All Subarrays is a hard coding problem on arrays, hash table and ordered set, asked in Google interviews.

The imbalance number of an array arr is the number of indices i (0 <= i < n - 1) of sarr = sorted(arr) for which sarr[i + 1] - sarr[i] > 1 — the number of gaps between neighbouring values once the array is sorted.

Given an integer array nums, return the sum of the imbalance numbers of all its non-empty contiguous subarrays.

Example 1

Input
nums = [2,3,1,4]
Output
3
Explanation
Only `[3,1]`, `[3,1,4]` and `[1,4]` have a gap (each exactly one); every other subarray sorts into consecutive values.

Example 2

Input
nums = [1,3,3,3,5]
Output
8
Explanation
Subarrays such as `[1,3,3,3,5]` sort to `[1,3,3,3,5]` with two gaps; equal values never form a gap.

Example 3

Input
nums = [1]
Output
0

Constraints

  • 1 <= nums.length <= 1000
  • 1 <= nums[i] <= nums.length
Write your solution here. Running it against the tests needs a free account — what you type comes with you.Sign in to run
/**
 * @param {number[]} nums
 * @return {number}
 */
var sumImbalanceNumbers = function(nums) {
    // Write your code here
    
};

Sign in to run your own test cases

Sign in

Sum of Imbalance Numbers of All Subarrays — Solution

Sum of Imbalance Numbers of All Subarrays solution explained: step-by-step approach, complexity and code in Python, Java, C++ and JavaScript. A hard problem.

Sum of Imbalance Numbers of All Subarrays is a hard coding problem on arrays, hash table and ordered set, asked in Google interviews.

  • Difficulty: Hard
  • Topics: Arrays, Hash Table, Ordered Set
  • Asked at: Google
  • Time limit: 2 s
  • Memory limit: 256 MB
  • Languages: JavaScript, TypeScript, Python, Java, C++, C, C#, Go, Kotlin, Swift, Rust, PHP and Ruby

Problem statement

The imbalance number of an array arr is the number of indices i (0 <= i < n - 1) of sarr = sorted(arr) for which sarr[i + 1] - sarr[i] > 1 — the number of gaps between neighbouring values once the array is sorted.

Given an integer array nums, return the sum of the imbalance numbers of all its non-empty contiguous subarrays.

Example 1

Input: nums = [2,3,1,4]
Output: 3
Explanation: Only `[3,1]`, `[3,1,4]` and `[1,4]` have a gap (each exactly one); every other subarray sorts into consecutive values.

Example 2

Input: nums = [1,3,3,3,5]
Output: 8
Explanation: Subarrays such as `[1,3,3,3,5]` sort to `[1,3,3,3,5]` with two gaps; equal values never form a gap.

Example 3

Input: nums = [1]
Output: 0

Constraints

  • 1 <= nums.length <= 1000
  • 1 <= nums[i] <= nums.length

Hints for Sum of Imbalance Numbers of All Subarrays

  1. Hint 1

    Sorting every subarray is far too slow. Fix the left end and grow the subarray one element at a time — can you update the imbalance in O(1) per step?

  2. Hint 2

    Think of the distinct values present as maximal runs of consecutive integers. The imbalance is exactly (number of runs) − 1.

  3. Hint 3

    Adding a value x that is already present changes nothing. A new x starts a run, but merges with the run of x - 1 if present and with the run of x + 1 if present — each merge removes one run.

How to solve Sum of Imbalance Numbers of All Subarrays

The sorted distinct values of a subarray split into maximal runs of consecutive integers, and each boundary between two runs is one gap — so imbalance = runs − 1. Runs can be maintained in O(1) as a subarray grows to the right, with a seen array over the small value range.

Approach

  1. For each left end i, clear a boolean array seen of size n + 2 and set runs = 0.
  2. Extend the right end j from i. Let x = nums[j]. If seen[x] is already set, the runs are unchanged.
  3. Otherwise mark it and set runs += 1, then runs -= 1 if seen[x - 1], and runs -= 1 if seen[x + 1].
  4. Add runs - 1 to the answer for the subarray nums[i..j].

Why it works

Duplicates never create a gap, so only the set of distinct values matters. That set is a union of maximal blocks of consecutive integers; sorted, consecutive blocks are separated by exactly one difference greater than 1, and inside a block every difference is 1 — hence imbalance = blocks − 1. A new value x is a block on its own unless x - 1 or x + 1 is present, in which case it glues onto (or bridges) those blocks, each neighbour reducing the count by one.

Complexity

  • Time — O(n^2)
  • Space — O(n)

Pitfalls

  • A repeated value must not change the run count — check seen[x] first.
  • Index x + 1 can be n + 1, so size the array n + 2.
  • The imbalance of a single-element subarray is 0 (one run), not −1 — the formula runs − 1 already gives 0 because there is always at least one run.

Reference solution

Python

from typing import List

def sumImbalanceNumbers(nums: List[int]) -> int:
    n = len(nums)
    total = 0
    for i in range(n):
        seen = [False] * (n + 2)
        runs = 0
        for j in range(i, n):
            x = nums[j]
            if not seen[x]:
                seen[x] = True
                runs += 1
                if seen[x - 1]:
                    runs -= 1
                if seen[x + 1]:
                    runs -= 1
            total += runs - 1
    return total

Java

public static int sumImbalanceNumbers(int[] nums) {
    int n = nums.length;
    int total = 0;
    for (int i = 0; i < n; i++) {
        boolean[] seen = new boolean[n + 2];
        int runs = 0;
        for (int j = i; j < n; j++) {
            int x = nums[j];
            if (!seen[x]) {
                seen[x] = true;
                runs++;
                if (seen[x - 1]) runs--;
                if (seen[x + 1]) runs--;
            }
            total += runs - 1;
        }
    }
    return total;
}

C++

int sumImbalanceNumbers(vector<int>& nums) {
    int n = nums.size();
    int total = 0;
    for (int i = 0; i < n; i++) {
        vector<bool> seen(n + 2, false);
        int runs = 0;
        for (int j = i; j < n; j++) {
            int x = nums[j];
            if (!seen[x]) {
                seen[x] = true;
                runs++;
                if (seen[x - 1]) runs--;
                if (seen[x + 1]) runs--;
            }
            total += runs - 1;
        }
    }
    return total;
}

JavaScript

var sumImbalanceNumbers = function(nums) {
    var n = nums.length;
    var total = 0;
    var seen = new Uint8Array(n + 2);
    for (var i = 0; i < n; i++) {
        seen.fill(0);
        var runs = 0;
        for (var j = i; j < n; j++) {
            var x = nums[j];
            if (!seen[x]) {
                seen[x] = 1;
                runs++;
                if (seen[x - 1]) runs--;
                if (seen[x + 1]) runs--;
            }
            total += runs - 1;
        }
    }
    return total;
};

Also on the editorial tab: C, C#, Go, Kotlin, PHP, Ruby, Rust, Swift, TypeScript.

All 1199 arrays problems · the whole catalogue

Learn the technique: Arrays · Hashing: Hash Maps and Hash Sets