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.
The brute force approach involves checking all possible quadruplets (i, j, k, l) in the array that satisfy the required conditions. This can be done using four nested loops. Given the constraints, however, this approach is highly inefficient with a time complexity of O(n^4). However, optimizations can be applied by pruning and breaking out early if conditions are not met to slightly ease the computation.
The solution checks each combination of indices (i, j, k, l) to see if the quadruplet satisfies the conditions nums[i] < nums[k] < nums[j] < nums[l]. While primarily a brute force method, minor optimizations reduce unnecessary checks based on conditions.
Python
The time complexity is O(n^4) due to four nested loops. Space complexity is O(1) as no additional space is used other than variables.
An optimized approach involves preprocessing information to avoid unnecessary checks. The idea is to use auxiliary arrays to store useful information that indicates how many elements suitable for being part of a quadruplet are smaller than or larger than a particular element. This helps in reducing the time taken to check conditions for the quadruplets.
This solution uses two auxiliary arrays: one (less_left) that records how many elements less than the current element are to its left, and another (great_right) that records how many elements greater than it are to its right. This precomputation allows us to efficiently count valid quadruplets.
Python
The time complexity is O(n^2) due to the need to construct and utilize the auxiliary arrays. Space complexity is O(n) for the storage of two additional arrays.
In this approach, iterate through each possible quadruplet using nested loops, ensuring the indices match the constraints: 0 <= i < j < k < l < n. Count valid quadruplets by checking if the conditions nums[i] < nums[k] < nums[j] < nums[l] are satisfied.
This C solution uses four nested loops to iterate over all possible quadruplets (i, j, k, l) as per given conditions. Each valid quadruplet that satisfies nums[i] < nums[k] < nums[j] < nums[l] increments the count. Finally, the function returns the count of such quadruplets.
Time Complexity: O(n^4) due to four nested loops.
Space Complexity: O(1) since we're using a constant amount of extra space.
This approach optimizes the search for quadruplets by preprocessing the input array to limit repeated comparisons. It focuses on exploring possibilities for 'j' and then uses data structures to store potential i, k, and l values to avoid redundant operations, significantly improving efficiency compared to the brute-force method.
This Python solution preprocesses to count potential i indices for each possible k index up to j. It avoids redundant computation by focusing only on valid index combinations, generally reducing comparison operations through preprocessing.
Time Complexity: O(n^3) because the innermost computation is reduced by preprocessing.
Space Complexity: O(n) due to auxiliary storage for preprocessing count arrays.
We can enumerate j and k in the quadruplet, then the problem is transformed into, for the current j and k:
l satisfy l > k and nums[l] > nums[j];i satisfy i < j and nums[i] < nums[k].We can use two two-dimensional arrays f and g to record these two pieces of information. Where f[j][k] represents how many l satisfy l > k and nums[l] > nums[j], and g[j][k] represents how many i satisfy i < j and nums[i] < nums[k].
Therefore, the answer is the sum of all f[j][k] times g[j][k].
The time complexity is O(n^2), and the space complexity is O(n^2). Where n is the length of the array.
| Approach | Complexity |
|---|---|
| Brute Force with Early Pruning | The time complexity is O(n^4) due to four nested loops. Space complexity is O(1) as no additional space is used other than variables. |
| Optimized Approach with Preprocessing | The time complexity is O(n^2) due to the need to construct and utilize the auxiliary arrays. Space complexity is O(n) for the storage of two additional arrays. |
| Nested Loop with Counting | Time Complexity: O(n^4) due to four nested loops. |
| Improved Counting with Preprocessing | Time Complexity: O(n^3) because the innermost computation is reduced by preprocessing. |
| Enumeration + Preprocessing | — |
| 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 |
2552. Count Increasing Quadruplets | Leetcode weekly contest • A Code Daily! • 1,956 views views
Watch 9 more video solutions →Practice Count Increasing Quadruplets with our built-in code editor and test cases.
Practice on FleetCode