comments | difficulty | edit_url | rating | source | tags | |||||
---|---|---|---|---|---|---|---|---|---|---|
true |
Hard |
2217 |
Biweekly Contest 62 Q4 |
|
You are given a 0-indexed 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 <= 105
-105 <= k, nums[i] <= 105
We can preprocess to get the prefix sum array
If we do not modify the array
If we modify the array
Finally, we return
The time complexity is
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
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 {
public:
int waysToPartition(vector<int>& nums, int k) {
int n = nums.size();
long long s[n];
s[0] = nums[0];
unordered_map<long long, int> right;
for (int i = 0; i < n - 1; ++i) {
right[s[i]]++;
s[i + 1] = s[i] + nums[i + 1];
}
int ans = 0;
if (s[n - 1] % 2 == 0) {
ans = right[s[n - 1] / 2];
}
unordered_map<long long, int> left;
for (int i = 0; i < n; ++i) {
int d = k - nums[i];
if ((s[n - 1] + d) % 2 == 0) {
int t = left[(s[n - 1] + d) / 2] + right[(s[n - 1] - d) / 2];
ans = max(ans, t);
}
left[s[i]]++;
right[s[i]]--;
}
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[:n-1] {
right[s[i]]++
s[i+1] = s[i] + nums[i+1]
}
if s[n-1]%2 == 0 {
ans = right[s[n-1]/2]
}
left := map[int]int{}
for i, x := range nums {
d := k - x
if (s[n-1]+d)%2 == 0 {
t := left[(s[n-1]+d)/2] + right[(s[n-1]-d)/2]
if ans < t {
ans = t
}
}
left[s[i]]++
right[s[i]]--
}
return
}