给定一个数组arr[]和一个整数X ,任务是打印最长的子数组,使其元素之和不能被X整除。如果不存在这样的子数组,则打印“-1” 。
注意:如果给定属性存在多个子数组,则打印其中任何一个。
例子:
Input: arr[] = {1, 2, 3} X = 3
Output: 2 3
Explanation:
The subarray {2, 3} has a sum of elements 5, which isn’t divisible by 3.
Input: arr[] = {2, 6} X = 2
Output: -1
Explanation:
All possible subarrays {1}, {2}, {1, 2} have an even sum.
Therefore, the answer is -1.
朴素方法:解决问题的最简单方法是生成所有可能的子数组并不断计算其总和。如果发现任何子数组的总和不能被X整除,则将长度与获得的最大长度( maxm )进行比较,并相应地更新maxm并更新子数组的起始索引和结束索引。最后,打印具有存储的开始和结束索引的子数组。如果没有这样的子数组,则打印“-1” 。
时间复杂度: O(N 2 )
辅助空间: O(1)
高效方法:为了优化上述方法,我们将找到前缀和后缀数组总和。请按照以下步骤操作:
- 生成前缀和数组和后缀和数组。
- 使用两个指针从[0, N – 1]迭代,并选择每个索引处元素的前缀和后缀和,该元素不能被X整除。存储子数组的起始索引和结束索引。
- 完成上述步骤后,如果存在总和不能被X整除的子数组,则打印具有存储的起始和结束索引的子数组。
- 如果没有这样的子数组,则打印“-1” 。
下面是上述方法的实现:
C++
#include
// C++ Program to implement
// the above approach
#include
using namespace std;
// Function to print the longest
// subarray with sum of elements
// not divisible by X
void max_length(int N, int x,
vector& v)
{
int i, a;
// Pref[] stores the prefix sum
// Suff[] stores the suffix sum
vector preff, suff;
int ct = 0;
for (i = 0; i < N; i++) {
a = v[i];
// If array element is
// divisibile by x
if (a % x == 0) {
// Increase count
ct += 1;
}
}
// If all the array elements
// are divisible by x
if (ct == N) {
// No subarray possible
cout << -1 << endl;
return;
}
// Reverse v to calculate the
// suffix sum
reverse(v.begin(), v.end());
suff.push_back(v[0]);
// Calculate the suffix sum
for (i = 1; i < N; i++) {
suff.push_back(v[i]
+ suff[i - 1]);
}
// Reverse to original form
reverse(v.begin(), v.end());
// Reverse the suffix sum array
reverse(suff.begin(), suff.end());
preff.push_back(v[0]);
// Calculate the prefix sum
for (i = 1; i < N; i++) {
preff.push_back(v[i]
+ preff[i - 1]);
}
int ans = 0;
// Stores the starting index
// of required subarray
int lp = 0;
// Stores the ending index
// of required subarray
int rp = N - 1;
for (i = 0; i < N; i++) {
// If suffix sum till i-th
// index is not divisible by x
if (suff[i] % x != 0
&& (ans < (N - 1))) {
lp = i;
rp = N - 1;
// Update the answer
ans = max(ans, N - i);
}
// If prefix sum till i-th
// index is not divisible by x
if (preff[i] % x != 0
&& (ans < (i + 1))) {
lp = 0;
rp = i;
// Update the answer
ans = max(ans, i + 1);
}
}
// Print the longest subarray
for (i = lp; i <= rp; i++) {
cout << v[i] << " ";
}
}
// Driver Code
int main()
{
int x = 3;
vector v = { 1, 3, 2, 6 };
int N = v.size();
max_length(N, x, v);
return 0;
}
Java
// Java program to implement
// the above approach
import java.util.*;
class GFG{
// Function to print the longest
// subarray with sum of elements
// not divisible by X
static void max_length(int N, int x,
int []v)
{
int i, a;
// Pref[] stores the prefix sum
// Suff[] stores the suffix sum
List preff = new Vector();
List suff = new Vector();
int ct = 0;
for(i = 0; i < N; i++)
{
a = v[i];
// If array element is
// divisibile by x
if (a % x == 0)
{
// Increase count
ct += 1;
}
}
// If all the array elements
// are divisible by x
if (ct == N)
{
// No subarray possible
System.out.print(-1 + "\n");
return;
}
// Reverse v to calculate the
// suffix sum
v = reverse(v);
suff.add(v[0]);
// Calculate the suffix sum
for(i = 1; i < N; i++)
{
suff.add(v[i] + suff.get(i - 1));
}
// Reverse to original form
v = reverse(v);
// Reverse the suffix sum array
Collections.reverse(suff);
preff.add(v[0]);
// Calculate the prefix sum
for(i = 1; i < N; i++)
{
preff.add(v[i] + preff.get(i - 1));
}
int ans = 0;
// Stores the starting index
// of required subarray
int lp = 0;
// Stores the ending index
// of required subarray
int rp = N - 1;
for(i = 0; i < N; i++)
{
// If suffix sum till i-th
// index is not divisible by x
if (suff.get(i) % x != 0 &&
(ans < (N - 1)))
{
lp = i;
rp = N - 1;
// Update the answer
ans = Math.max(ans, N - i);
}
// If prefix sum till i-th
// index is not divisible by x
if (preff.get(i) % x != 0 &&
(ans < (i + 1)))
{
lp = 0;
rp = i;
// Update the answer
ans = Math.max(ans, i + 1);
}
}
// Print the longest subarray
for(i = lp; i <= rp; i++)
{
System.out.print(v[i] + " ");
}
}
static int[] reverse(int a[])
{
int i, n = a.length, t;
for(i = 0; i < n / 2; i++)
{
t = a[i];
a[i] = a[n - i - 1];
a[n - i - 1] = t;
}
return a;
}
// Driver Code
public static void main(String[] args)
{
int x = 3;
int []v = { 1, 3, 2, 6 };
int N = v.length;
max_length(N, x, v);
}
}
// This code is contributed by PrinciRaj1992
Python3
# Python3 program to implement
# the above approach
# Function to print the longest
# subarray with sum of elements
# not divisible by X
def max_length(N, x, v):
# Pref[] stores the prefix sum
# Suff[] stores the suffix sum
preff, suff = [], []
ct = 0
for i in range(N):
a = v[i]
# If array element is
# divisibile by x
if a % x == 0:
# Increase count
ct += 1
# If all the array elements
# are divisible by x
if ct == N:
# No subarray possible
print(-1)
return
# Reverse v to calculate the
# suffix sum
v.reverse()
suff.append(v[0])
# Calculate the suffix sum
for i in range(1, N):
suff.append(v[i] + suff[i - 1])
# Reverse to original form
v.reverse()
# Reverse the suffix sum array
suff.reverse()
preff.append(v[0])
# Calculate the prefix sum
for i in range(1, N):
preff.append(v[i] + preff[i - 1])
ans = 0
# Stores the starting index
# of required subarray
lp = 0
# Stores the ending index
# of required subarray
rp = N - 1
for i in range(N):
# If suffix sum till i-th
# index is not divisible by x
if suff[i] % x != 0 and ans < N - 1:
lp = i
rp = N - 1
# Update the answer
ans = max(ans, N - i)
# If prefix sum till i-th
# index is not divisible by x
if preff[i] % x != 0 and ans < i + 1:
lp = 0
rp = i
# Update the answer
ans = max(ans, i + 1)
# Print the longest subarray
for i in range(lp, rp + 1):
print(v[i], end = " ")
# Driver code
x = 3
v = [ 1, 3, 2, 6 ]
N = len(v)
max_length(N, x, v)
# This code is contributed by Stuti Pathak
C#
// C# program to implement
// the above approach
using System;
using System.Collections.Generic;
class GFG{
// Function to print the longest
// subarray with sum of elements
// not divisible by X
static void max_length(int N, int x,
int []v)
{
int i, a;
// Pref[] stores the prefix sum
// Suff[] stores the suffix sum
List preff = new List();
List suff = new List();
int ct = 0;
for(i = 0; i < N; i++)
{
a = v[i];
// If array element is
// divisibile by x
if (a % x == 0)
{
// Increase count
ct += 1;
}
}
// If all the array elements
// are divisible by x
if (ct == N)
{
// No subarray possible
Console.Write(-1 + "\n");
return;
}
// Reverse v to calculate the
// suffix sum
v = reverse(v);
suff.Add(v[0]);
// Calculate the suffix sum
for(i = 1; i < N; i++)
{
suff.Add(v[i] + suff[i - 1]);
}
// Reverse to original form
v = reverse(v);
// Reverse the suffix sum array
suff.Reverse();
preff.Add(v[0]);
// Calculate the prefix sum
for(i = 1; i < N; i++)
{
preff.Add(v[i] + preff[i - 1]);
}
int ans = 0;
// Stores the starting index
// of required subarray
int lp = 0;
// Stores the ending index
// of required subarray
int rp = N - 1;
for(i = 0; i < N; i++)
{
// If suffix sum till i-th
// index is not divisible by x
if (suff[i] % x != 0 &&
(ans < (N - 1)))
{
lp = i;
rp = N - 1;
// Update the answer
ans = Math.Max(ans, N - i);
}
// If prefix sum till i-th
// index is not divisible by x
if (preff[i] % x != 0 &&
(ans < (i + 1)))
{
lp = 0;
rp = i;
// Update the answer
ans = Math.Max(ans, i + 1);
}
}
// Print the longest subarray
for(i = lp; i <= rp; i++)
{
Console.Write(v[i] + " ");
}
}
static int[] reverse(int []a)
{
int i, n = a.Length, t;
for(i = 0; i < n / 2; i++)
{
t = a[i];
a[i] = a[n - i - 1];
a[n - i - 1] = t;
}
return a;
}
// Driver Code
public static void Main(String[] args)
{
int x = 3;
int []v = { 1, 3, 2, 6 };
int N = v.Length;
max_length(N, x, v);
}
}
// This code is contributed by PrinciRaj1992
输出:
3 2 6
时间复杂度: O(N)
辅助空间: O(N)