给定一个大小为N的数组arr []和一个整数k ,我们的任务是找到元素之和不能被k整除的最长子数组的长度。如果不存在这样的子数组,则返回-1。
例子:
Input: arr[] = {8, 4, 3, 1, 5, 9, 2}, k = 2
Output: 5
Explanation:
The subarray is {8, 4, 3, 1, 5} with sum = 21, is not divisible by 2.
Input: arr[] = {6, 3, 12, 15}, k = 3
Output: -1
Explanation:
There is no subarray which is not divisible by 3.
天真的方法:想法是考虑所有子数组并返回最长子数组的长度,以使其元素的总和不能被k整除。
时间复杂度: O(N 2 )
辅助空间: O(N)
高效的方法:主要的观察结果是,删除被k整除的元素不会对解决方案有所帮助,但是,如果我们删除未被k整除的元素,则总和将不会被k整除。
- 因此,令k的最左边的非多重位于索引左,和k的最右边的非多重位于索引对。
- 删除直到索引左的前缀元素或到索引右的后缀元素,并删除元素数量较少的元素。
- 此问题有两个极端的情况。首先是,如果数组的每个元素都可以被k整除,则不存在这样的子数组,因此返回-1。其次,如果整个数组中的某些不能被k整除,则子数组将是数组本身,因此返回数组的大小。
下面是上述方法的实现:
C++
// C++ Program to find the length of
// the longest subarray whose sum is
// not divisible by integer K
#include
using namespace std;
// Function to find the longest subarray
// with sum is not divisible by k
int MaxSubarrayLength(int arr[], int n, int k)
{
// left is the index of the
// leftmost element that is
// not divisible by k
int left = -1;
// right is the index of the
// rightmost element that is
// not divisible by k
int right;
// sum of the array
int sum = 0;
for (int i = 0; i < n; i++) {
// Find the element that
// is not multiple of k
if ((arr[i] % k) != 0) {
// left = -1 means we are
// finding the leftmost
// element that is not
// divisible by k
if (left == -1) {
left = i;
}
// Updating the
// rightmost element
right = i;
}
// update the sum of the
// array up to the index i
sum += arr[i];
}
// Check if the sum of the
// array is not divisible
// by k, then return the
// size of array
if ((sum % k) != 0) {
return n;
}
// All elements of array
// are divisible by k,
// then no such subarray
// possible so return -1
else if (left == -1) {
return -1;
}
else {
// length of prefix elements
// that can be removed
int prefix_length = left + 1;
// length of suffix elements
// that can be removed
int suffix_length = n - right;
// Return the length of
// subarray after removing
// the elements which have
// lesser number of elements
return n - min(prefix_length,
suffix_length);
}
}
// Driver Code
int main()
{
int arr[] = { 6, 3, 12, 15 };
int n = sizeof(arr) / sizeof(arr[0]);
int K = 3;
cout << MaxSubarrayLength(arr, n, K);
return 0;
}
Java
// Java program to find the length of
// the longest subarray whose sum is
// not divisible by integer K
import java.util.*;
class GFG{
// Function to find the longest subarray
// with sum is not divisible by k
static int MaxSubarrayLength(int arr[], int n,
int k)
{
// left is the index of the
// leftmost element that is
// not divisible by k
int left = -1;
// right is the index of the
// rightmost element that is
// not divisible by k
int right = 0;
// sum of the array
int sum = 0;
for(int i = 0; i < n; i++)
{
// Find the element that
// is not multiple of k
if ((arr[i] % k) != 0)
{
// left = -1 means we are
// finding the leftmost
// element that is not
// divisible by k
if (left == -1)
{
left = i;
}
// Updating the
// rightmost element
right = i;
}
// Update the sum of the
// array up to the index i
sum += arr[i];
}
// Check if the sum of the
// array is not divisible
// by k, then return the
// size of array
if ((sum % k) != 0)
{
return n;
}
// All elements of array
// are divisible by k,
// then no such subarray
// possible so return -1
else if (left == -1)
{
return -1;
}
else
{
// Length of prefix elements
// that can be removed
int prefix_length = left + 1;
// Length of suffix elements
// that can be removed
int suffix_length = n - right;
// Return the length of
// subarray after removing
// the elements which have
// lesser number of elements
return n - Math.min(prefix_length,
suffix_length);
}
}
// Driver code
public static void main(String[] args)
{
int arr[] = { 6, 3, 12, 15 };
int n = arr.length;
int K = 3;
System.out.println(MaxSubarrayLength(arr, n, K));
}
}
// This code is contributed by offbeat
Python3
# Python3 program to find the length of
# the longest subarray whose sum is
# not divisible by integer
# Function to find the longest subarray
# with sum is not divisible by k
def MaxSubarrayLength(arr, n, k):
# left is the index of the
# leftmost element that is
# not divisible by k
left = -1
# sum of the array
sum = 0
for i in range(n):
# Find the element that
# is not multiple of k
if ((arr[i] % k) != 0):
# left = -1 means we are
# finding the leftmost
# element that is not
# divisible by k
if (left == -1):
left = i
# Updating the
# rightmost element
right = i
# Update the sum of the
# array up to the index i
sum += arr[i]
# Check if the sum of the
# array is not divisible
# by k, then return the
# size of array
if ((sum % k) != 0):
return n
# All elements of array
# are divisible by k,
# then no such subarray
# possible so return -1
elif(left == -1):
return -1
else:
# length of prefix elements
# that can be removed
prefix_length = left + 1
# length of suffix elements
# that can be removed
suffix_length = n - right
# Return the length of
# subarray after removing
# the elements which have
# lesser number of elements
return n - min(prefix_length,
suffix_length)
# Driver Code
if __name__ == "__main__":
arr = [ 6, 3, 12, 15 ]
n = len(arr)
K = 3
print(MaxSubarrayLength(arr, n, K))
# This code is contributed by chitranayal
C#
// C# program to find the length of
// the longest subarray whose sum is
// not divisible by integer K
using System;
class GFG{
// Function to find the longest subarray
// with sum is not divisible by k
static int MaxSubarrayLength(int []arr, int n,
int k)
{
// left is the index of the
// leftmost element that is
// not divisible by k
int left = -1;
// right is the index of the
// rightmost element that is
// not divisible by k
int right = 0;
// sum of the array
int sum = 0;
for(int i = 0; i < n; i++)
{
// Find the element that
// is not multiple of k
if ((arr[i] % k) != 0)
{
// left = -1 means we are
// finding the leftmost
// element that is not
// divisible by k
if (left == -1)
{
left = i;
}
// Updating the
// rightmost element
right = i;
}
// Update the sum of the
// array up to the index i
sum += arr[i];
}
// Check if the sum of the
// array is not divisible
// by k, then return the
// size of array
if ((sum % k) != 0)
{
return n;
}
// All elements of array
// are divisible by k,
// then no such subarray
// possible so return -1
else if (left == -1)
{
return -1;
}
else
{
// Length of prefix elements
// that can be removed
int prefix_length = left + 1;
// Length of suffix elements
// that can be removed
int suffix_length = n - right;
// Return the length of
// subarray after removing
// the elements which have
// lesser number of elements
return n - Math.Min(prefix_length,
suffix_length);
}
}
// Driver code
public static void Main(string[] args)
{
int []arr = { 6, 3, 12, 15 };
int n = arr.Length;
int K = 3;
Console.Write(MaxSubarrayLength(arr, n, K));
}
}
// This code is contributed by rutvik_56
输出:
-1
时间复杂度: O(N)
辅助空间: O(1)