Skip to content

Instantly share code, notes, and snippets.

@Ifihan
Created December 6, 2025 21:52
Show Gist options
  • Select an option

  • Save Ifihan/347dcdda46add95054bb4e599234ad95 to your computer and use it in GitHub Desktop.

Select an option

Save Ifihan/347dcdda46add95054bb4e599234ad95 to your computer and use it in GitHub Desktop.
Count Partitions With Max-Min Difference at Most K

Question

Approach

I use dynamic programming where dp[r] is the number of ways to partition the first r elements (r from 0..n) and dp[0]=1. For each right end r (1-based for prefix length) I find the smallest l (0-based index) such that the subarray nums[l..r-1] has max - min ≤ k; then dp[r] = sum(dp[i] for i in [l..r-1]). I compute that range-sum in O(1) with a running prefix-sum array pref. To get every l in amortized O(1) time I maintain a sliding window with two monotonic deques for max and min and advance the left pointer until the window becomes valid.

Implementation

class Solution:
    def countPartitions(self, nums: List[int], k: int) -> int:
        MOD = 10**9 + 7
        n = len(nums)
        dp0 = 1
        pref_prev = dp0
        
        left = 0
        maxdq = deque() 
        mindq = deque()  
        
        dp_r = 0
        
        for r in range(1, n + 1):
            x = nums[r - 1]
            while maxdq and maxdq[-1][0] < x:
                maxdq.pop()
            maxdq.append((x, r - 1))
            while mindq and mindq[-1][0] > x:
                mindq.pop()
            mindq.append((x, r - 1))
            
            while maxdq and mindq and (maxdq[0][0] - mindq[0][0] > k):
                if maxdq and maxdq[0][1] == left:
                    maxdq.popleft()
                if mindq and mindq[0][1] == left:
                    mindq.popleft()
                left += 1
            
            if left == 0:
                dp_r = pref_prev 
            else:
                pass
            break

        pref = [0] * (n + 1) 
        pref[0] = 1 
        
        left = 0
        maxdq.clear()
        mindq.clear()
        
        for r in range(1, n + 1):
            x = nums[r - 1]
            while maxdq and maxdq[-1][0] < x:
                maxdq.pop()
            maxdq.append((x, r - 1))
            while mindq and mindq[-1][0] > x:
                mindq.pop()
            mindq.append((x, r - 1))
            
            while maxdq and mindq and (maxdq[0][0] - mindq[0][0] > k):
                if maxdq and maxdq[0][1] == left:
                    maxdq.popleft()
                if mindq and mindq[0][1] == left:
                    mindq.popleft()
                left += 1
            
            dp_r = (pref[r - 1] - (pref[left - 1] if left > 0 else 0)) % MOD
            pref[r] = (pref[r - 1] + dp_r) % MOD
        
        return dp_r % MOD

Complexities

  • Time: O(n)
  • Space: O(n)
image
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment