Welcome to Subscribe On Youtube
Formatted question description: https://leetcode.ca/all/2025.html
2025. Maximum Number of Ways to Partition an Array (Hard)
You are given a 0indexed integer array nums
of length n
. The number of ways to partition nums
is the number of pivot
indices that satisfy both conditions:
1 <= pivot < n
nums[0] + nums[1] + ... + nums[pivot  1] == nums[pivot] + nums[pivot + 1] + ... + nums[n  1]
You are also given an integer k
. You can choose to change the value of one element of nums
to k
, or to leave the array unchanged.
Return the maximum possible number of ways to partition nums
to satisfy both conditions after changing at most one element.
Example 1:
Input: nums = [2,1,2], k = 3 Output: 1 Explanation: One optimal approach is to change nums[0] to k. The array becomes [3,1,2]. There is one way to partition the array:  For pivot = 2, we have the partition [3,1  2]: 3 + 1 == 2.
Example 2:
Input: nums = [0,0,0], k = 1 Output: 2 Explanation: The optimal approach is to leave the array unchanged. There are two ways to partition the array:  For pivot = 1, we have the partition [0  0,0]: 0 == 0 + 0.  For pivot = 2, we have the partition [0,0  0]: 0 + 0 == 0.
Example 3:
Input: nums = [22,4,25,20,15,15,16,7,19,10,0,13,14], k = 33 Output: 4 Explanation: One optimal approach is to change nums[2] to k. The array becomes [22,4,33,20,15,15,16,7,19,10,0,13,14]. There are four ways to partition the array.
Constraints:
n == nums.length
2 <= n <= 10^{5}
10^{5} <= k, nums[i] <= 10^{5}
Similar Questions:
Solution 1. Frequency Map
Given array A
, we can compute an array diff
where diff[i] = (A[0] + .. + A[i1])  (A[i] + .. + A[N1])
(1 <= i < N
), i.e. sum of left part minus sum of right part.
If we don’t do any replacement, the answer is the number of 0
s in the diff
array.
If we replace A[i]
with k
, then diff[1]
to diff[i]
decrease by d
, and diff[i+1]
to diff[N1]
increase by d
, where d = k  A[i]
. Again, the answer is the number of 0
s in this new diff
array.
Instead of changing the diff
array (taking O(N)
time), we can simply count the number of d
in diff[1..i]
and number of d
in diff[(i+1)..(N1)]
(taking O(1)
time).
So, we can use two frequency maps L
and R
which are the frequency maps of diff[1..i]
and diff[(i+1)..(N1)]
respectively.
We scan from left to right. For each A[i]
, we try to update ans
with L[d] + R[d]
where d = k  A[i]
, and update the frequency maps.

// OJ: https://leetcode.com/problems/maximumnumberofwaystopartitionanarray/ // Time: O(N) // Space: O(N) class Solution { public: int waysToPartition(vector<int>& A, int k) { long sum = accumulate(begin(A), end(A), 0L), N = A.size(); unordered_map<long, int> L, R; for (long i = 0, left = 0; i < N  1; ++i) { left += A[i]; long right = sum  left; R[left  right]++; } int ans = R[0]; // If we don't do any replacement, answer is the number of `0`s in the frequency map for (long i = 0, left = 0; i < N; ++i) { left += A[i]; long right = sum  left, d = k  A[i]; ans = max(ans, L[d] + R[d]); // If we replace `A[i]` with `k`, we will get `L[d] + R[d]` pivots R[left  right]; // transfer the frequency from `R` to `L`. L[left  right]++; } return ans; } };

class Solution { public int waysToPartition(int[] nums, int k) { int n = nums.length; int[] s = new int[n]; s[0] = nums[0]; Map<Integer, Integer> right = new HashMap<>(); for (int i = 0; i < n  1; ++i) { right.merge(s[i], 1, Integer::sum); s[i + 1] = s[i] + nums[i + 1]; } int ans = 0; if (s[n  1] % 2 == 0) { ans = right.getOrDefault(s[n  1] / 2, 0); } Map<Integer, Integer> left = new HashMap<>(); for (int i = 0; i < n; ++i) { int d = k  nums[i]; if ((s[n  1] + d) % 2 == 0) { int t = left.getOrDefault((s[n  1] + d) / 2, 0) + right.getOrDefault((s[n  1]  d) / 2, 0); ans = Math.max(ans, t); } left.merge(s[i], 1, Integer::sum); right.merge(s[i], 1, Integer::sum); } return ans; } }

class Solution: def waysToPartition(self, nums: List[int], k: int) > int: n = len(nums) s = [nums[0]] * n right = defaultdict(int) for i in range(1, n): s[i] = s[i  1] + nums[i] right[s[i  1]] += 1 ans = 0 if s[1] % 2 == 0: ans = right[s[1] // 2] left = defaultdict(int) for v, x in zip(s, nums): d = k  x if (s[1] + d) % 2 == 0: t = left[(s[1] + d) // 2] + right[(s[1]  d) // 2] if ans < t: ans = t left[v] += 1 right[v] = 1 return ans

func waysToPartition(nums []int, k int) (ans int) { n := len(nums) s := make([]int, n) s[0] = nums[0] right := map[int]int{} for i := range nums[:n1] { right[s[i]]++ s[i+1] = s[i] + nums[i+1] } if s[n1]%2 == 0 { ans = right[s[n1]/2] } left := map[int]int{} for i, x := range nums { d := k  x if (s[n1]+d)%2 == 0 { t := left[(s[n1]+d)/2] + right[(s[n1]d)/2] if ans < t { ans = t } } left[s[i]]++ right[s[i]] } return }
Example:
A = [2, 1, 2]
diff = [_, 1, 1]
If we change the diff
array.
// replace A[0] with 3
A = [3, 1, 2]
diff change +1 +1
diff = [_, 2, 0]
// replace A[1] with 3
A = [2, 3, 2]
diff change 4 +4
diff = [_, 3, 3]
// replace A[2] with 3
A = [2, 1, 3]
diff change 1 1
diff = [_, 0, 2]
If we use frequency maps:
diff = [_, 1, 1]
// If we don't do any replacement
[_  1, 1]
answer = R[0] = 0
// replace A[0] with 3, d = 1
[_  1, 1]
answer = L[1] + R[1] = 0 + 1 = 1
// replace A[1] with 3, d = 4
[_ 1  1]
answer = L[4] + R[4] = 0 + 0 = 0
// replace A[2] with 3, d = 1
[_ 1 1 ]
answer = L[1] + R[1] = 1 + 0 = 1
Discuss
https://leetcode.com/problems/maximumnumberofwaystopartitionanarray/discuss/1499365/C%2B%2BFrequencyMapO(N)