找到使左侧部分的 0 和右侧部分的 1 的计数之和最大化的分区
给定一个长度为N的二进制数组nums ,任务是在给定数组中找到所有可能的分区,使得左侧 0 的计数和右侧 1 的计数之和最大化。
示例:
Input: nums = {0, 0, 1, 0}
Output: 2, 4
Explanation: Division at index
index – 0: numsleft is []. numsright is [0, 0, 1, 0]. The sum is 0 + 1 = 1.
index – 1: numsleft is [0]. numsright is [0, 1, 0]. The sum is 1 + 1 = 2.
index – 2: numsleft is [0, 0]. numsright is [1, 0]. The sum is 2 + 1 = 3.
index – 3: numsleft is [0, 0, 1]. numsright is [0]. The sum is 2 + 0 = 2.
index – 4: numsleft is [0, 0, 1, 0]. numsright is []. The sum is 3 + 0 = 3.
Therefore partition at index 2 and 4 gives the highest possible sum 3.
Input: nums= {0, 0, 0, 1, 0, 1, 1}
Output: 3, 5
Explanation:
If we divide the array at index 3 then numsLeft is 3 and numsRight is 3. The sum is 3 + 3 = 6
If we divide the array at index 5 then numsLeft is 4 and numsRight is 2. The sum is 4 + 2 = 6
Any other division will result in score less than 6.
方法:这个想法是使用前缀 sum 使得 sum[i+1] 将是 A[0] + ... + A[i]。
- 查找数组的前缀和并将其存储在数组和中。
- 对于每个索引i,左侧部分将有i - sum[i]个零,右侧部分将有sum[N] - sum[i]个。
- 通过将左侧部分和右侧部分相加来计算分数。
- 将分数与之前的最高分数进行比较
- 如果当前分数大于前一个分数,则更新最大分数并将 i 放入结果数组中。
- 如果当前分数等于前一个最大值,则在前一个结果数组中推送此索引 i。
- 完成遍历后返回结果数组。
以下是上述方法的实现:
C++
// C++ program to find partitions
// that maximizes sum of count of 0's
// in left part and count
// of 1's in right part
#include
using namespace std;
// Function to find all possible
// max sum partitions
vector findPartitions(vector& A)
{
int N = A.size(), mx = 0;
// Prefix sum array
vector sum(N + 1, 0), ans;
for (int i = 0; i < N; ++i)
sum[i + 1] = sum[i] + A[i];
// Find the partitions
// with maximum prefix sum
for (int i = 0; i <= N; ++i) {
// Calculate score for
// the current index
int score = i - sum[i]
+ sum[N] - sum[i];
// Compare current score
// with previous max
if (score > mx) {
ans = { i };
mx = score;
}
// If current score
// is greater than
// previous then push
// in the ans array.
else if (score == mx)
ans.push_back(i);
}
// Returning the resultant
// array of indices
return ans;
}
// Driver code
int main()
{
vector res,
arr{ 0, 0, 0, 1, 0, 1, 1 };
res = findPartitions(arr);
for (auto it : res)
cout << it << " ";
return 0;
}
Java
// Java program to find partitions
// that maximizes sum of count of 0's
// in left part and count
// of 1's in right part
import java.util.*;
class GFG{
// Function to find all possible
// max sum partitions
static VectorfindPartitions(int []A)
{
int N = A.length, mx = 0;
// Prefix sum array
Vector ans = new Vector();
int []sum = new int[N + 1];
for (int i = 0; i < N; ++i)
sum[i + 1] = sum[i] + A[i];
// Find the partitions
// with maximum prefix sum
for (int i = 0; i <= N; ++i) {
// Calculate score for
// the current index
int score = i - sum[i]
+ sum[N] - sum[i];
// Compare current score
// with previous max
if (score > mx) {
ans = new Vector();
ans.add(i);
mx = score;
}
// If current score
// is greater than
// previous then push
// in the ans array.
else if (score == mx)
ans.add(i);
}
// Returning the resultant
// array of indices
return ans;
}
// Driver code
public static void main(String[] args)
{
int[] arr = { 0, 0, 0, 1, 0, 1, 1 };
Vector res = findPartitions(arr);
for (int it : res)
System.out.print(it+ " ");
}
}
// This code is contributed by shikhasingrajput
Python3
# Python program to find partitions
# that maximizes sum of count of 0's
# in left part and count
# of 1's in right part
# Function to find all possible
# max sum partitions
def findPartitions(A):
N = len(A)
mx = 0
# Prefix sum array
sum = []
for i in range(0, N + 1):
sum.append(0)
ans = []
for i in range(0, N):
sum[i + 1] = sum[i] + A[i];
# Find the partitions
# with maximum prefix sum
for i in range(0, N + 1):
# Calculate score for
# the current index
score = i - sum[i] + sum[N] - sum[i]
# Compare current score
# with previous max
if (score > mx):
ans.clear()
ans.append(i)
mx = score
# If current score
# is greater than
# previous then push
# in the ans array.
elif (score == mx):
ans.append(i)
# Returning the resultant
# array of indices
return ans
# Driver code
res = []
arr = [ 0, 0, 0, 1, 0, 1, 1 ]
res = findPartitions(arr)
print(res)
# This code is contributed by Samim Hossain Mondal
C#
// C# program to find partitions
// that maximizes sum of count of 0's
// in left part and count
// of 1's in right part
using System;
using System.Collections;
class GFG
{
// Function to find all possible
// max sum partitions
static ArrayList findPartitions(ArrayList A)
{
int N = A.Count, mx = 0;
// Prefix sum array
int []sum = new int[N + 1];
for(int i = 0; i < N + 1; i++) {
sum[i] = 0;
}
ArrayList ans = new ArrayList();
for (int i = 0; i < N; ++i)
sum[i + 1] = sum[i] + (int)A[i];
// Find the partitions
// with maximum prefix sum
for (int i = 0; i <= N; ++i) {
// Calculate score for
// the current index
int score = i - sum[i]
+ sum[N] - sum[i];
// Compare current score
// with previous max
if (score > mx) {
ans.Clear();
ans.Add(i);
mx = score;
}
// If current score
// is greater than
// previous then push
// in the ans array.
else if (score == mx)
ans.Add(i);
}
// Returning the resultant
// array of indices
return ans;
}
// Driver code
public static void Main()
{
ArrayList arr = new ArrayList();
arr.Add(0);
arr.Add(0);
arr.Add(0);
arr.Add(1);
arr.Add(0);
arr.Add(1);
arr.Add(1);
ArrayList res = findPartitions(arr);
for(int i = 0; i < res.Count; i++)
Console.Write(res[i] + " ");
}
}
// This code is contributed by Samim Hossain Mondal.
Javascript
3 5
时间复杂度:O(N)
辅助空间:O(N)