Watch 10 video solutions for Count Increasing Quadruplets, a hard level problem involving Array, Dynamic Programming, Binary Indexed Tree. This walkthrough by A Code Daily! has 1,956 views views. Want to try solving it yourself? Practice on FleetCode or read the detailed text solution.
Given a 0-indexed integer array nums of size n containing all numbers from 1 to n, return the number of increasing quadruplets.
A quadruplet (i, j, k, l) is increasing if:
0 <= i < j < k < l < n, andnums[i] < nums[k] < nums[j] < nums[l].
Example 1:
Input: nums = [1,3,2,4,5] Output: 2 Explanation: - When i = 0, j = 1, k = 2, and l = 3, nums[i] < nums[k] < nums[j] < nums[l]. - When i = 0, j = 1, k = 2, and l = 4, nums[i] < nums[k] < nums[j] < nums[l]. There are no other quadruplets, so we return 2.
Example 2:
Input: nums = [1,2,3,4] Output: 0 Explanation: There exists only one quadruplet with i = 0, j = 1, k = 2, l = 3, but since nums[j] < nums[k], we return 0.
Constraints:
4 <= nums.length <= 40001 <= nums[i] <= nums.lengthnums are unique. nums is a permutation.Problem Overview: Given an array nums, count the number of index quadruplets (i, j, k, l) such that i < j < k < l and nums[i] < nums[k] < nums[j] < nums[l]. The challenge is enforcing both index ordering and value ordering efficiently without checking every possible combination.
Approach 1: Brute Force with Early Pruning (O(n^4) time, O(1) space)
Enumerate all quadruplets using four nested loops over indices i, j, k, and l. For each combination, check the ordering constraint directly. Small optimizations prune cases early, such as skipping when nums[i] >= nums[k] or nums[j] >= nums[l]. The algorithm is straightforward but scales poorly because the search space grows as n^4. Useful mainly for understanding the problem or validating optimized solutions.
Approach 2: Nested Loop with Counting (O(n^3) time, O(1) space)
Fix two middle indices and reduce the remaining search to counting valid values. Iterate j and k, ensuring j < k. For each pair where nums[k] < nums[j], scan the left side for indices i where nums[i] < nums[k] and scan the right side for indices l where nums[l] > nums[j]. Multiply the counts to get the number of quadruplets using this (j,k) pair. This eliminates one loop but still requires scanning ranges repeatedly.
Approach 3: Improved Counting with Preprocessing (O(n^2) time, O(n^2) space)
Precompute helpful counts to avoid rescanning the array. For each index pair, track how many elements to the right are greater than a given value and how many to the left are smaller. When iterating over (j, k) pairs with j < k and nums[k] < nums[j], combine these precomputed values to determine how many valid i and l indices exist. This converts repeated scans into constant‑time lookups, reducing the overall complexity to O(n^2). The approach relies heavily on careful counting and is closely related to techniques used in dynamic programming and prefix sum style preprocessing.
Approach 4: Optimized Approach with Preprocessing / Fenwick Tree (O(n^2) time, O(n log n) updates)
A more scalable variant uses frequency structures such as a Fenwick Tree (Binary Indexed Tree). While iterating through the array, maintain counts of values already seen and values remaining. For each potential (j, k) pair, query the structure to count elements smaller than nums[k] on the left and larger than nums[j] on the right. Fenwick Trees support prefix queries and updates in O(log n), making the counting step efficient. This technique is common in advanced array counting problems and when using a Binary Indexed Tree.
Recommended for interviews: Start by describing the brute force enumeration to demonstrate understanding of the constraints. Interviewers usually expect the optimized counting approach with preprocessing or Fenwick Tree, which reduces the problem to O(n^2) time. The key insight is fixing the middle pair (j, k) and counting valid elements on both sides instead of explicitly enumerating all four indices.
| Approach | Time | Space | When to Use |
|---|---|---|---|
| Brute Force with Early Pruning | O(n^4) | O(1) | Understanding the constraints or validating correctness for small inputs |
| Nested Loop with Counting | O(n^3) | O(1) | When optimizing brute force but avoiding extra memory |
| Improved Counting with Preprocessing | O(n^2) | O(n^2) | Best balance of clarity and speed for interview settings |
| Fenwick Tree / Binary Indexed Tree | O(n^2 log n) | O(n) | Useful when using ordered counting structures or extending to larger value ranges |