给定一个整数数组arr[]和一个整数K ,任务是找到需要删除的最小子数组的长度,使得剩余数组元素的总和可以被K整除。不允许移除整个阵列。如果不可能,则打印“-1” 。
例子:
Input: arr[] = {3, 1, 4, 2}, K = 6
Output: 1
Explanation: Sum of array elements = 10, which is not divisible by 6. After removing the subarray {4}, sum of the remaining elements is 6. Therefore, the length of the removed subarray is 1.
Input: arr[] = {3, 6, 7, 1}, K = 9
Output: 2
Explanation: Sum of array elements = 17, which is not divisible by 9. After removing the subarray {7, 1} and the, sum of the remaining elements is 9. Therefore, the length of the removed subarray is 2.
朴素的方法:最简单的方法是从给定的数组arr[]生成所有可能的子数组,不包括长度为N的子数组。现在,找到子数组的最小长度,使得数组所有元素的总和与该子数组中元素的总和之间的差能被K整除。如果不存在这样的子数组,则打印“-1” 。
时间复杂度: O(N 2 )
辅助空间: O(1)
高效的方法:为了优化上述方法,该想法基于以下观察:
((total_sum – subarray_sum) % K + subarray_sum % K) must be equal to total_sum % K.
But, (total_sum – subarray_sum) % K == 0 should be true.
Therefore, total_sum % K == subarray_sum % K, so both subarray_sum and total_sum should leave the same remainder when divided by K. Hence, the task is to find the length of the smallest subarray whose sum of elements will leave a remainder of (total_sum % K).
请按照以下步骤解决此问题:
- 将变量res初始化为 INT_MAX 来存储要移除的子数组的最小长度。
- 计算total_sum和除以K 后的余数。
- 创建一个辅助数组modArr[]来存储每个arr[i]被K除时的余数:
modArr[i] = (arr[i] + K) % K.
where,
K has been added while calculating the remainder to handle the case of negative integers.
- 遍历给定的数组并维护一个 unordered_map 以存储遇到的余数的最近位置,并跟踪具有与target_remainder相同的余数的最小所需子数组。
- 如果映射中存在任何等于(curr_remainder – target_remainder + K) % K 的键,则将该子数组长度存储在变量 res 中,作为找到的res和当前长度的最小值。
- 以上后,如果res没有改变,则打印“-1”,否则打印res的值。
下面是上述方法的实现:
C++
// C++ program for the above approach
#include
using namespace std;
// Function to find the length of the
// smallest subarray to be removed such
// that sum of elements is divisible by K
void removeSmallestSubarray(int arr[],
int n, int k)
{
// Stores the remainder of each
// arr[i] when divided by K
int mod_arr[n];
// Stores total sum of elements
int total_sum = 0;
// K has been added to each arr[i]
// to handle -ve integers
for (int i = 0; i < n; i++) {
mod_arr[i] = (arr[i] + k) % k;
// Update the total sum
total_sum += arr[i];
}
// Remainder when total_sum
// is divided by K
int target_remainder
= total_sum % k;
// If given array is already
// divisible by K
if (target_remainder == 0) {
cout << "0";
return;
}
// Stores curr_remainder and the
// most recent index at which
// curr_remainder has occured
unordered_map map1;
map1[0] = -1;
int curr_remainder = 0;
// Stores required answer
int res = INT_MAX;
for (int i = 0; i < n; i++) {
// Add current element to
// curr_sum and take mod
curr_remainder = (curr_remainder
+ arr[i] + k)
% k;
// Update current remainder index
map1[curr_remainder] = i;
int mod
= (curr_remainder
- target_remainder
+ k)
% k;
// If mod already exists in map
// the subarray exists
if (map1.find(mod) != map1.end())
res = min(res, i - map1[mod]);
}
// If not possible
if (res == INT_MAX || res == n) {
res = -1;
}
// Print the result
cout << res;
}
// Driver Code
int main()
{
// Given array arr[]
int arr[] = { 3, 1, 4, 2 };
// Size of array
int N = sizeof(arr) / sizeof(arr[0]);
// Given K
int K = 6;
// Function Call
removeSmallestSubarray(arr, N, K);
return 0;
}
Java
// Java program for the
// above approach
import java.util.*;
class GFG{
// Function to find the length of the
// smallest subarray to be removed such
// that sum of elements is divisible by K
static void removeSmallestSubarray(int arr[],
int n, int k)
{
// Stores the remainder of each
// arr[i] when divided by K
int []mod_arr = new int[n];
// Stores total sum of
// elements
int total_sum = 0;
// K has been added to each
// arr[i] to handle -ve integers
for (int i = 0; i < n; i++)
{
mod_arr[i] = (arr[i] +
k) % k;
// Update the total sum
total_sum += arr[i];
}
// Remainder when total_sum
// is divided by K
int target_remainder =
total_sum % k;
// If given array is already
// divisible by K
if (target_remainder == 0)
{
System.out.print("0");
return;
}
// Stores curr_remainder and the
// most recent index at which
// curr_remainder has occured
HashMap map1 =
new HashMap<>();
map1.put(0, -1);
int curr_remainder = 0;
// Stores required answer
int res = Integer.MAX_VALUE;
for (int i = 0; i < n; i++)
{
// Add current element to
// curr_sum and take mod
curr_remainder = (curr_remainder +
arr[i] + k) % k;
// Update current remainder
// index
map1.put(curr_remainder, i);
int mod = (curr_remainder -
target_remainder +
k) % k;
// If mod already exists in
// map the subarray exists
if (map1.containsKey(mod))
res = Math.min(res, i -
map1.get(mod));
}
// If not possible
if (res == Integer.MAX_VALUE ||
res == n)
{
res = -1;
}
// Print the result
System.out.print(res);
}
// Driver Code
public static void main(String[] args)
{
// Given array arr[]
int arr[] = {3, 1, 4, 2};
// Size of array
int N = arr.length;
// Given K
int K = 6;
// Function Call
removeSmallestSubarray(arr, N, K);
}
}
// This code is contributed by gauravrajput1
Python3
# Python3 program for the above approach
import sys
# Function to find the length of the
# smallest subarray to be removed such
# that sum of elements is divisible by K
def removeSmallestSubarray(arr, n, k):
# Stores the remainder of each
# arr[i] when divided by K
mod_arr = [0] * n
# Stores total sum of elements
total_sum = 0
# K has been added to each arr[i]
# to handle -ve integers
for i in range(n) :
mod_arr[i] = (arr[i] + k) % k
# Update the total sum
total_sum += arr[i]
# Remainder when total_sum
# is divided by K
target_remainder = total_sum % k
# If given array is already
# divisible by K
if (target_remainder == 0):
print("0")
return
# Stores curr_remainder and the
# most recent index at which
# curr_remainder has occured
map1 = {}
map1[0] = -1
curr_remainder = 0
# Stores required answer
res = sys.maxsize
for i in range(n):
# Add current element to
# curr_sum and take mod
curr_remainder = (curr_remainder +
arr[i] + k) % k
# Update current remainder index
map1[curr_remainder] = i
mod = (curr_remainder -
target_remainder + k) % k
# If mod already exists in map
# the subarray exists
if (mod in map1.keys()):
res = min(res, i - map1[mod])
# If not possible
if (res == sys.maxsize or res == n):
res = -1
# Print the result
print(res)
# Driver Code
# Given array arr[]
arr = [ 3, 1, 4, 2 ]
# Size of array
N = len(arr)
# Given K
K = 6
# Function Call
removeSmallestSubarray(arr, N, K)
# This code is contributed by susmitakundugoaldanga
C#
// C# program for the
// above approach
using System;
using System.Collections.Generic;
class GFG{
// Function to find the length of the
// smallest subarray to be removed such
// that sum of elements is divisible by K
static void removeSmallestSubarray(int []arr,
int n, int k)
{
// Stores the remainder of each
// arr[i] when divided by K
int []mod_arr = new int[n];
// Stores total sum of
// elements
int total_sum = 0;
// K has been added to each
// arr[i] to handle -ve integers
for(int i = 0; i < n; i++)
{
mod_arr[i] = (arr[i] + k) % k;
// Update the total sum
total_sum += arr[i];
}
// Remainder when total_sum
// is divided by K
int target_remainder = total_sum % k;
// If given array is already
// divisible by K
if (target_remainder == 0)
{
Console.Write("0");
return;
}
// Stores curr_remainder and the
// most recent index at which
// curr_remainder has occured
Dictionary map1 = new Dictionary();
map1.Add(0, -1);
int curr_remainder = 0;
// Stores required answer
int res = int.MaxValue;
for(int i = 0; i < n; i++)
{
// Add current element to
// curr_sum and take mod
curr_remainder = (curr_remainder +
arr[i] + k) % k;
// Update current remainder
// index
map1[curr_remainder] = i;
int mod = (curr_remainder -
target_remainder +
k) % k;
// If mod already exists in
// map the subarray exists
if (map1.ContainsKey(mod))
res = Math.Min(res, i -
map1[mod]);
}
// If not possible
if (res == int.MaxValue ||
res == n)
{
res = -1;
}
// Print the result
Console.Write(res);
}
// Driver Code
public static void Main(String[] args)
{
// Given array []arr
int []arr = { 3, 1, 4, 2 };
// Size of array
int N = arr.Length;
// Given K
int K = 6;
// Function Call
removeSmallestSubarray(arr, N, K);
}
}
// This code is contributed by 29AjayKumar
1
时间复杂度: O(N)
辅助空间: O(N)
如果您想与行业专家一起参加直播课程,请参阅Geeks Classes Live