给定一个由N个整数组成的数组arr [] ,任务是重新排列该数组,以使从该数组的第一个索引开始的所有子数组的总和为非零。如果无法生成这种排列,则打印“ -1” 。
例子:
Input: arr[] = {-1, 1, -2, 3}
Output: {-1, -2, 1, 3}
Explanation: One of the possible rearrangement is {-1, -2, 1, 3}.
Subarrays starting from index 0 are {-1}, {-1, -2}, {-1, -2, 1} and {-1, -2, 1, 3}. None of the above subarrays have sum 0.
Input: arr[] = {0, 0, 0, 0}
Output: -1
方法:如果给定数组处于以下两种配置中的任何一种,则可以从给定数组中获得所需的数组:
- 如果给定数组按升序排序,则可以通过将子数组的最后一个元素替换为大于它的元素来处理总和为零的第一个子数组。
- 类似地,在以降序排序的数组中,通过用小于它的元素将子数组的第一个元素替换为总和零,以确保此后的总和为负。
请按照以下步骤解决问题:
- 当数组以升序排序时:
- 以升序对数组arr []进行排序,并找到数组的前i个元素的总和(0≤i≤N)。
- 当遇到零和时,将使前缀和无效的元素(即第i个元素)替换为数组中最大的元素:
- 如果数组的最大元素等于导致无效的整数,则移至第二个配置。
- 如果最大元素大于有问题的元素,则此替换可确保正和而不是零。
- 当数组按降序排序时:
- 按降序对数组arr []进行排序,然后开始查找数组的最后i个元素的总和(0≤i≤N)。
- 当遇到零和时,将使前缀和无效的元素(即第i个元素)替换为数组中的最小元素:
- 如果数组的最小元素等于导致无效的整数,则无法重新排列数组arr []。
- 如果最小元素小于有问题的元素,则此替换可确保负和而不是零。
下面是上述方法的实现:
C++
// C++ program for the above approach
#include
using namespace std;
// Function to rearrange the array such
// that sum of all elements of subarrays
// from the 1st index is non-zero
void rearrangeArray(int a[], int N)
{
// Initialize sum of subarrays
int sum = 0;
// Sum of all elements of array
for (int i = 0; i < N; i++) {
sum += a[i];
}
// If sum is 0, the required
// array could never be formed
if (sum == 0) {
cout << "-1";
return;
}
// If sum is non zero, array
// might be formed
sum = 0;
int b = 0;
// Sort array in ascending order
sort(a, a + N);
for (int i = 0; i < N; i++) {
sum += a[i];
// When current subarray sum
// becomes 0 replace it with
// the largest element
if (sum == 0) {
if (a[i] != a[N - 1]) {
sum -= a[i];
// Swap Operation
swap(a[i], a[N - 1]);
sum += a[i];
}
// If largest element is same
// as element to be replaced,
// then rearrangement impossible
else {
b = 1;
break;
}
}
}
// If b = 1, then rearrangement
// is not possible. Hence check
// with reverse configuration
if (b == 1) {
b = 0;
sum = 0;
// Sort array in descending order
sort(a, a + N, greater());
// When current subarray sum
// becomes 0 replace it with
// the smallest element
for (int i = N - 1; i >= 0; i--) {
sum += a[i];
if (sum == 0) {
if (a[i] != a[0]) {
sum -= a[i];
// Swap Operation
swap(a[i], a[0]);
sum += a[i];
}
// If smallest element is same
// as element to be replaced,
// then rearrangement impossible
else {
b = 1;
break;
}
}
}
}
// If neither of the configurations
// worked then print "-1"
if (b == 1) {
cout << "-1";
return;
}
// Otherwise, print the formed
// rearrangement
for (int i = 0; i < N; i++) {
cout << a[i] << " ";
}
}
// Driver Code
int main()
{
// Given array
int arr[] = { 1, -1, 2, 4, 0 };
// Size of array
int N = sizeof(arr) / sizeof(arr[0]);
// Function Call
rearrangeArray(arr, N);
return 0;
}
Java
// Java program for the above approach
import java.util.*;
import java.util.Arrays;
import java.util.Collections;
class GFG{
// Function to rearrange the array such
// that sum of all elements of subarrays
// from the 1st index is non-zero
static void rearrangeArray(int a[], int N)
{
// Initialize sum of subarrays
int sum = 0;
// Sum of all elements of array
for(int i = 0; i < N; i++)
{
sum += a[i];
}
// If sum is 0, the required
// array could never be formed
if (sum == 0)
{
System.out.print("-1");
return;
}
// If sum is non zero, array
// might be formed
sum = 0;
int b = 0;
// Sort array in ascending order
Arrays.sort(a);
for(int i = 0; i < N; i++)
{
sum += a[i];
// When current subarray sum
// becomes 0 replace it with
// the largest element
if (sum == 0)
{
if (a[i] != a[N - 1])
{
sum -= a[i];
// Swap Operation
int temp = a[i];
a[i] = a[N - 1];
a[N - 1] = temp;
sum += a[i];
}
// If largest element is same
// as element to be replaced,
// then rearrangement impossible
else
{
b = 1;
break;
}
}
}
// If b = 1, then rearrangement
// is not possible. Hence check
// with reverse configuration
if (b == 1)
{
b = 0;
sum = 0;
// Sort array in descending order
Arrays.sort(a);
// When current subarray sum
// becomes 0 replace it with
// the smallest element
for(int i = N - 1; i >= 0; i--)
{
sum += a[i];
if (sum == 0)
{
if (a[i] != a[0])
{
sum -= a[i];
// Swap Operation
int temp = a[i];
a[i] = a[0];
a[0] = temp;
sum += a[i];
}
// If smallest element is same
// as element to be replaced,
// then rearrangement impossible
else
{
b = 1;
break;
}
}
}
}
// If neither of the configurations
// worked then print "-1"
if (b == 1)
{
System.out.print("-1" + " ");
return;
}
// Otherwise, print the formed
// rearrangement
for(int i = 0; i < N; i++)
{
System.out.print(a[i] + " ");
}
}
// Driver Code
public static void main(String args[])
{
// Given array
int arr[] = { 1, -1, 2, 4, 0 };
// Size of array
int N = arr.length;
// Function Call
rearrangeArray(arr, N);
}
}
// This code is contributed by SURENDRA_GANGWAR
Python3
# Python3 program for the above approach
# Function to rearrange the array such
# that sum of all elements of subarrays
# from the 1st index is non-zero
def rearrangeArray(a, N):
# Initialize sum of subarrays
sum = 0
# Sum of all elements of array
for i in range(N):
sum += a[i]
# If sum is 0, the required
# array could never be formed
if (sum == 0):
print("-1")
return
# If sum is non zero, array
# might be formed
sum = 0
b = 0
# Sort array in ascending order
a = sorted(a)
for i in range(N):
sum += a[i]
# When current subarray sum
# becomes 0 replace it with
# the largest element
if (sum == 0):
if (a[i] != a[N - 1]):
sum -= a[i]
# Swap Operation
a[i], a[N - 1] = a[N - 1], a[i]
sum += a[i]
# If largest element is same
# as element to be replaced,
# then rearrangement impossible
else:
b = 1
break
# If b = 1, then rearrangement
# is not possible. Hence check
# with reverse configuration
if (b == 1):
b = 0
sum = 0
# Sort array in descending order
a = sorted(a)
a = a[::-1]
# When current subarray sum
# becomes 0 replace it with
# the smallest element
for i in range(N - 1, -1, -1):
sum += a[i]
if (sum == 0):
if (a[i] != a[0]):
sum -= a[i]
# Swap Operation
a[i], a[0] = a[0], a[i]
sum += a[i]
# If smallest element is same
# as element to be replaced,
# then rearrangement impossible
else:
b = 1
break
# If neither of the configurations
# worked then pr"-1"
if (b == 1):
print("-1")
return
# Otherwise, print the formed
# rearrangement
for i in range(N):
print(a[i], end = " ")
# Driver Code
if __name__ == '__main__':
# Given array
arr = [ 1, -1, 2, 4, 0 ]
# Size of array
N = len(arr)
# Function Call
rearrangeArray(arr, N)
# This code is contributed by mohit kumar 29
C#
// C# program for the above approach
using System;
class GFG{
// Function to rearrange the array such
// that sum of all elements of subarrays
// from the 1st index is non-zero
static void rearrangeArray(int [] a, int N)
{
// Initialize sum of subarrays
int sum = 0;
// Sum of all elements of array
for(int i = 0; i < N; i++)
{
sum += a[i];
}
// If sum is 0, the required
// array could never be formed
if (sum == 0)
{
Console.Write("-1");
return;
}
// If sum is non zero, array
// might be formed
sum = 0;
int b = 0;
// Sort array in ascending order
Array.Sort(a);
for(int i = 0; i < N; i++)
{
sum += a[i];
// When current subarray sum
// becomes 0 replace it with
// the largest element
if (sum == 0)
{
if (a[i] != a[N - 1])
{
sum -= a[i];
// Swap Operation
int temp = a[i];
a[i] = a[N - 1];
a[N - 1] = temp;
sum += a[i];
}
// If largest element is same
// as element to be replaced,
// then rearrangement impossible
else
{
b = 1;
break;
}
}
}
// If b = 1, then rearrangement
// is not possible. Hence check
// with reverse configuration
if (b == 1)
{
b = 0;
sum = 0;
// Sort array in descending order
Array.Sort(a);
// When current subarray sum
// becomes 0 replace it with
// the smallest element
for(int i = N - 1; i >= 0; i--)
{
sum += a[i];
if (sum == 0)
{
if (a[i] != a[0])
{
sum -= a[i];
// Swap Operation
int temp = a[i];
a[i] = a[0];
a[0] = temp;
sum += a[i];
}
// If smallest element is same
// as element to be replaced,
// then rearrangement impossible
else
{
b = 1;
break;
}
}
}
}
// If neither of the configurations
// worked then print "-1"
if (b == 1)
{
Console.Write("-1" + " ");
return;
}
// Otherwise, print the formed
// rearrangement
for(int i = 0; i < N; i++)
{
Console.Write(a[i] + " ");
}
}
// Driver Code
public static void Main()
{
// Given array
int[] arr = { 1, -1, 2, 4, 0 };
// Size of array
int N = arr.Length;
// Function Call
rearrangeArray(arr, N);
}
}
// This code is contributed by chitranayal
输出:
-1 0 4 2 1
时间复杂度: O(N * log N)
辅助空间: O(1)