从给定数组的前后删除的最小数量,以使 0 和 1 的计数相等
给定一个数组arr[]仅包含0和1 。任务是从数组的前面和后面找到最小的删除次数,使得新修改的数组由相等数量的 0 和 1 组成。
例子:
Input: arr[] = {1, 1, 0, 1}
Output: 2
Explanation: Two ones from the starting or first and last element can be removed
Input: arr[] = {0, 1, 1, 1, 0}
Output: 3
Explanation: First three elements can be removed or last three elements
方法:可以使用贪心方法解决问题。由于数组的每个元素都可以是 0 或 1,因此将0 视为 -1,将 1 视为 1本身。然后找到由相等数量的 1 和 0 组成的最大子数组。然后从数组的总大小中减去这个子数组的大小。这种方法之所以有效,是因为该方法在任何时候都试图保持子数组的大小尽可能大,以便只能从末端删除最少数量的元素。请参阅下图以更好地理解。
从图中可以看出,随着中间部分 y的大小增加(由相等数量的 0 和 1组成),部分 (x + z) 的大小自动减小。
下面是上述方法的实现。
C++
// C++ code for the above approach
#include
using namespace std;
// Function to calculate
// the minimum number of deletions
int solve(vector arr)
{
// Size of the array
int sz = arr.size();
// Store running sum of array
int summe = 0;
// To store index of the sum
unordered_map index;
// Initially sum is 0 with index -1
index[summe] = -1;
// Store length of largest subarray
int ans = 0, curr_len = 0;
for (int i = 0; i < sz; i++) {
// If curr_element is 0, add -1
if (arr[i] == 0)
summe -= 1;
// If curr_element is 1, add 1
else
summe += 1;
// Check if sum already occurred
if (index.find(summe) != index.end()) {
// Calculate curr subarray length
curr_len = i - index[summe];
// Store the maximum value
// in the ans
ans = max(ans, curr_len);
}
// Sum occurring for the first time
// So store this sum with current index
else
index[summe] = i;
}
// Return diff between size
// and largest subarray
return (sz - ans);
}
// Driver code
int main()
{
vector arr = { 1, 1, 0, 1 };
int val = solve(arr);
cout << val;
}
// This code is contributed by Samim Hossain Mondal.
Java
// Java code for the above approach
import java.util.*;
class GFG{
// Function to calculate
// the minimum number of deletions
static int solve(int[] arr)
{
// Size of the array
int sz = arr.length;
// Store running sum of array
int summe = 0;
// To store index of the sum
HashMap index = new HashMap();
// Initially sum is 0 with index -1
index.put(summe, -1);
// Store length of largest subarray
int ans = 0, curr_len = 0;
for (int i = 0; i < sz; i++) {
// If curr_element is 0, add -1
if (arr[i] == 0)
summe -= 1;
// If curr_element is 1, add 1
else
summe += 1;
// Check if sum already occurred
if (index.containsKey(summe) ) {
// Calculate curr subarray length
curr_len = i - index.get(summe);
// Store the maximum value
// in the ans
ans = Math.max(ans, curr_len);
}
// Sum occurring for the first time
// So store this sum with current index
else
index.put(summe, i);
}
// Return diff between size
// and largest subarray
return (sz - ans);
}
// Driver code
public static void main(String[] args)
{
int []arr = { 1, 1, 0, 1 };
int val = solve(arr);
System.out.print(val);
}
}
// This code is contributed by 29AjayKumar
Python3
# Python code to implement the given approach
from collections import defaultdict
class Solution:
# Function to calculate
# the minimum number of deletions
def solve(self, arr):
# Size of the array
size = len(arr)
# Store running sum of array
summe = 0
# To store index of the sum
index = defaultdict(int)
# Initially sum is 0 with index -1
index[summe] = -1
# Store length of largest subarray
ans = 0
for i in range(size):
# If curr_element is 0, add -1
if (arr[i] == 0):
summe -= 1
# If curr_element is 1, add 1
else:
summe += 1
# Check if sum already occurred
if (summe in index):
# Calculate curr subarray length
curr_len = i - index[summe]
# Store the maximum value
# in the ans
ans = max(ans, curr_len)
# Sum occurring for the first time
# So store this sum with current index
else:
index[summe] = i
# Return diff between size
# and largest subarray
return (size - ans)
if __name__ == "__main__":
arr = [1, 1, 0, 1]
obj = Solution()
val = obj.solve(arr)
print(val)
C#
// C# code for the above approach
using System;
using System.Collections.Generic;
class GFG{
// Function to calculate
// the minimum number of deletions
static int solve(int[] arr)
{
// Size of the array
int sz = arr.Length;
// Store running sum of array
int summe = 0;
// To store index of the sum
Dictionary index = new Dictionary();
// Initially sum is 0 with index -1
index.Add(summe, -1);
// Store length of largest subarray
int ans = 0, curr_len = 0;
for (int i = 0; i < sz; i++) {
// If curr_element is 0, add -1
if (arr[i] == 0)
summe -= 1;
// If curr_element is 1, add 1
else
summe += 1;
// Check if sum already occurred
if (index.ContainsKey(summe) ) {
// Calculate curr subarray length
curr_len = i - index[summe];
// Store the maximum value
// in the ans
ans = Math.Max(ans, curr_len);
}
// Sum occurring for the first time
// So store this sum with current index
else
index[summe] = i;
}
// Return diff between size
// and largest subarray
return (sz - ans);
}
// Driver code
public static void Main()
{
int []arr = { 1, 1, 0, 1 };
int val = solve(arr);
Console.Write(val);
}
}
// This code is contributed by gfgking
Javascript
输出
2
时间复杂度: O(N)
辅助空间: O(1)