给定一个整数K和一个大小为N的数组A[] ,任务是使用最少的操作次数创建一个总和为K的新数组,其中在每个操作中,可以从A[的开头或结尾删除一个元素]并附加到新数组。如果无法用总和K生成新数组,则打印-1 。如果有多个答案,请打印其中任何一个。
例子
Input: K = 6, A[] = {1, 2, 3, 1, 3}, N = 5
Output: 1 3 2
Explanation: Operation 1: Removing A[0] modifies A[] to {2, 3, 1, 3}. Sum = 1.
Operation 2: Removing A[3] modifies A[] to {2, 1, 3}. Sum = 4.
Operation 3: Removing A[0] modifies A[] to {1, 3}. Sum = 6.
Input: K = 5, A[] = {1, 2, 7}, N = 3
Output: -1
朴素的方法:按照以下步骤解决问题:
- 任务是找到两个最小长度的子数组,一个从数组的开头开始,一个从数组的末尾开始(可能是空的),这样它们的总和等于K 。
- 从左边遍历数组并计算需要从右边移除的子数组,使得总和为K 。
下面是上述方法的实现:
C++
// C++ program for the above approach
#include
using namespace std;
// Function to find the minimum number of
// elements required to be removed from
// the ends of an array to obtain a sum K
int minSizeArr(int A[], int N, int K)
{
// Number of elements removed from the
// left and right ends of the array
int leftTaken = N, rightTaken = N;
// Sum of left and right subarrays
int leftSum = 0, rightSum = 0;
// No element is taken from left initially
for (int left = -1; left < N; left++) {
if (left != -1)
leftSum += A[left];
rightSum = 0;
// Start taking elements from right side
for (int right = N - 1; right > left; right--) {
rightSum += A[right];
if (leftSum + rightSum == K) {
// (left + 1): Count of elements
// removed from the left
// (N-right): Count of elements
// removed from the right
if (leftTaken + rightTaken
> (left + 1) + (N - right)) {
leftTaken = left + 1;
rightTaken = N - right;
}
break;
}
// If sum is greater than K
if (leftSum + rightSum > K)
break;
}
}
if (leftTaken + rightTaken <= N) {
for (int i = 0; i < leftTaken; i++)
cout << A[i] << " ";
for (int i = 0; i < rightTaken; i++)
cout << A[N - i - 1] << " ";
}
// If it is not possible to obtain sum K
else
cout << -1;
}
// Driver Code
int main()
{
int N = 7;
// Given Array
int A[] = { 3, 2, 1, 1, 1, 1, 3 };
// Given target sum
int K = 10;
minSizeArr(A, N, K);
return 0;
}
Java
// Java program for the above approach
import java.util.*;
class GFG{
// Function to find the minimum number of
// elements required to be removed from
// the ends of an array to obtain a sum K
static void minSizeArr(int A[], int N, int K)
{
// Number of elements removed from the
// left and right ends of the array
int leftTaken = N, rightTaken = N;
// Sum of left and right subarrays
int leftSum = 0, rightSum = 0;
// No element is taken from left initially
for (int left = -1; left < N; left++) {
if (left != -1)
leftSum += A[left];
rightSum = 0;
// Start taking elements from right side
for (int right = N - 1; right > left; right--)
{
rightSum += A[right];
if (leftSum + rightSum == K) {
// (left + 1): Count of elements
// removed from the left
// (N-right): Count of elements
// removed from the right
if (leftTaken + rightTaken
> (left + 1) + (N - right)) {
leftTaken = left + 1;
rightTaken = N - right;
}
break;
}
// If sum is greater than K
if (leftSum + rightSum > K)
break;
}
}
if (leftTaken + rightTaken <= N) {
for (int i = 0; i < leftTaken; i++)
System.out.print( A[i] + " ");
for (int i = 0; i < rightTaken; i++)
System.out.print(A[N - i - 1] + " ");
}
// If it is not possible to obtain sum K
else
System.out.print(-1);
}
// Driver code
public static void main(String[] args)
{
int N = 7;
// Given Array
int A[] = { 3, 2, 1, 1, 1, 1, 3 };
// Given target sum
int K = 10;
minSizeArr(A, N, K);
}
}
// This code is contributed by splevel62.
Python3
# Python3 program for the above approach
# Function to find the minimum number of
# elements required to be removed from
# the ends of an array to obtain a sum K
def minSizeArr(A, N, K):
# Number of elements removed from the
# left and right ends of the array
leftTaken = N
rightTaken = N
# Sum of left and right subarrays
leftSum = 0
rightSum = 0
# No element is taken from left initially
for left in range(-1, N):
if (left != -1):
leftSum += A[left]
rightSum = 0
# Start taking elements from right side
for right in range(N - 1, left, -1):
rightSum += A[right]
if (leftSum + rightSum == K):
# (left + 1): Count of elements
# removed from the left
# (N-right): Count of elements
# removed from the right
if (leftTaken + rightTaken >
(left + 1) + (N - right)):
leftTaken = left + 1
rightTaken = N - right
break
# If sum is greater than K
if (leftSum + rightSum > K):
break
if (leftTaken + rightTaken <= N):
for i in range(leftTaken):
print(A[i], end = " ")
for i in range(rightTaken):
print(A[N - i - 1], end = " ")
# If it is not possible to obtain sum K
else:
print(-1)
# Driver Code
if __name__ == "__main__":
N = 7
# Given Array
A = [ 3, 2, 1, 1, 1, 1, 3 ]
# Given target sum
K = 10
minSizeArr(A, N, K)
# This code is contributed by ukasp
C#
// C# program for the above approach
using System;
class GFG {
// Function to find the smallest
// array that can be removed from
// the ends of an array to obtain sum K
static void minSizeArr(int[] A, int N, int K)
{
// Number of elements removed from the
// left and right ends of the array
int leftTaken = N, rightTaken = N;
// Sum of left and right subarrays
int leftSum = 0, rightSum = 0;
// No element is taken from left initially
for (int left = -1; left < N; left++) {
if (left != -1)
leftSum += A[left];
rightSum = 0;
// Start taking elements from right side
for (int right = N - 1; right > left; right--)
{
rightSum += A[right];
if (leftSum + rightSum == K) {
// (left + 1): Count of elements
// removed from the left
// (N-right): Count of elements
// removed from the right
if (leftTaken + rightTaken
> (left + 1) + (N - right)) {
leftTaken = left + 1;
rightTaken = N - right;
}
break;
}
// If sum is greater than K
if (leftSum + rightSum > K)
break;
}
}
if (leftTaken + rightTaken <= N) {
for (int i = 0; i < leftTaken; i++)
Console.Write( A[i] + " ");
for (int i = 0; i < rightTaken; i++)
Console.Write(A[N - i - 1] + " ");
}
// If it is not possible to obtain sum K
else
Console.Write(-1);
}
// Driver Code
public static void Main()
{
int N = 7;
// Given Array
int[] A = { 3, 2, 1, 1, 1, 1, 3 };
// Given target sum
int K = 10;
minSizeArr(A, N, K);
}
}
// This code is contributed by code_hunt.
Javascript
C++
// C++ program for the above approach
#include
using namespace std;
// Function to find the smallest
// array that can be removed from
// the ends of an array to obtain sum K
void minSizeArr(int A[], int N, int K)
{
int sum = 0;
// Sum of complete array
for (int i = 0; i < N; i++)
sum += A[i];
// If given number is greater
// than sum of the array
if (K > sum) {
cout << -1;
return;
}
// If number is equal to
// the sum of array
if (K == sum) {
for (int i = 0; i < N; i++) {
cout << A[i] << " ";
}
return;
}
// tar is sum of middle subarray
int tar = sum - K;
// Find the longest subarray
// with sum equal to tar
unordered_map um;
um[0] = -1;
int left, right;
int cur = 0, maxi = -1;
for (int i = 0; i < N; i++) {
cur += A[i];
if (um.find(cur - tar) != um.end()
&& i - um[cur - tar] > maxi) {
maxi = i - um[cur - tar];
right = i;
left = um[cur - tar];
}
if (um.find(cur) == um.end())
um[cur] = i;
}
// If there is no subarray with
// sum equal to tar
if (maxi == -1)
cout << -1;
else {
for (int i = 0; i <= left; i++)
cout << A[i] << " ";
for (int i = 0; i < right; i++)
cout << A[N - i - 1] << " ";
}
}
// Driver Code
int main()
{
int N = 7;
// Given Array
int A[] = { 3, 2, 1, 1, 1, 1, 3 };
// Given target sum
int K = 10;
minSizeArr(A, N, K);
return 0;
}
Java
// Java program for the above approach
import java.io.*;
import java.util.*;
class GFG {
// Function to find the smallest
// array that can be removed from
// the ends of an array to obtain sum K
static void minSizeArr(int A[], int N, int K)
{
int sum = 0;
// Sum of complete array
for (int i = 0; i < N; i++)
sum += A[i];
// If given number is greater
// than sum of the array
if (K > sum) {
System.out.print(-1);
return;
}
// If number is equal to
// the sum of array
if (K == sum) {
for (int i = 0; i < N; i++) {
System.out.print(A[i] + " ");
}
return;
}
// tar is sum of middle subarray
int tar = sum - K;
// Find the longest subarray
// with sum equal to tar
HashMap um = new HashMap();
um.put(0, -1);
int left = 0, right = 0;
int cur = 0, maxi = -1;
for (int i = 0; i < N; i++) {
cur += A[i];
if (um.containsKey(cur - tar)
&& i - um.get(cur - tar) > maxi) {
maxi = i - um.get(cur - tar);
right = i;
left = um.get(cur - tar);
}
if (!um.containsKey(cur))
um.put(cur, i);
}
// If there is no subarray with
// sum equal to tar
if (maxi == -1)
System.out.println(-1);
else {
for (int i = 0; i <= left; i++)
System.out.print(A[i] + " ");
for (int i = 0; i < right; i++)
System.out.print(A[N - i - 1] + " ");
}
}
// Driver Code
public static void main (String[] args) {
int N = 7;
// Given Array
int A[] = { 3, 2, 1, 1, 1, 1, 3 };
// Given target sum
int K = 10;
minSizeArr(A, N, K);
}
}
// This code is contributed by Dharanendra L V.
Python3
# python 3 program for the above approach
# Function to find the smallest
# array that can be removed from
# the ends of an array to obtain sum K
def minSizeArr(A, N, K):
sum = 0
# Sum of complete array
for i in range(N):
sum += A[i]
# If given number is greater
# than sum of the array
if (K > sum):
print(-1);
return
# If number is equal to
# the sum of array
if (K == sum):
for i in range(N):
print(A[i],end = " ")
return
# tar is sum of middle subarray
tar = sum - K
# Find the longest subarray
# with sum equal to tar
um = {}
um[0] = -1
left = 0
right = 0
cur = 0
maxi = -1
for i in range(N):
cur += A[i]
if((cur - tar) in um and (i - um[cur - tar]) > maxi):
maxi = i - um[cur - tar]
right = i
left = um[cur - tar]
if(cur not in um):
um[cur] = i
# If there is no subarray with
# sum equal to tar
if (maxi == -1):
print(-1)
else:
for i in range(left+1):
print(A[i], end = " ")
for i in range(right):
print(A[N - i - 1], end = " ")
# Driver Code
if __name__ == '__main__':
N = 7
# Given Array
A = [3, 2, 1, 1, 1, 1, 3]
# Given target sum
K = 10
minSizeArr(A, N, K)
# This code is contributed by SURENDRA_GANGWAR.
C#
// C# program for
// the above approach
using System;
using System.Collections.Generic;
class GFG{
// Function to find the smallest
// array that can be removed from
// the ends of an array to obtain sum K
static void minSizeArr(int[] A, int N, int K)
{
int sum = 0;
// Sum of complete array
for(int i = 0; i < N; i++)
sum += A[i];
// If given number is greater
// than sum of the array
if (K > sum)
{
Console.WriteLine(-1);
return;
}
// If number is equal to
// the sum of array
if (K == sum)
{
for(int i = 0; i < N; i++)
{
Console.Write(A[i] + " ");
}
return;
}
// tar is sum of middle subarray
int tar = sum - K;
// Find the longest subarray
// with sum equal to tar
Dictionary um = new Dictionary();
um[0] = -1;
int left = 0, right = 0;
int cur = 0, maxi = -1;
for(int i = 0; i < N; i++)
{
cur += A[i];
if (um.ContainsKey(cur - tar) &&
i - um[cur - tar] > maxi)
{
maxi = i - um[cur - tar];
right = i;
left = um[cur - tar];
}
if (!um.ContainsKey(cur))
um[cur] = i;
}
// If there is no subarray with
// sum equal to tar
if (maxi == -1)
Console.Write(-1);
else
{
for(int i = 0; i <= left; i++)
Console.Write(A[i] + " ");
for(int i = 0; i < right; i++)
Console.Write(A[N - i - 1] + " ");
}
}
// Driver code
static public void Main()
{
int N = 7;
// Given Array
int[] A = { 3, 2, 1, 1, 1, 1, 3 };
// Given target sum
int K = 10;
minSizeArr(A, N, K);
}
}
// This code is contributed by offbeat
Javascript
输出:
3 2 3 1 1
时间复杂度: O(N 2 )
辅助空间: O(1)
高效方法:按照以下步骤优化上述方法:
- 计算数组A[]的元素总和并将其存储在一个变量中,比如Total 。
- 这个问题可以看作是用总和(Total – K)找到最大大小的子数组。
- 其余元素将加起来为K 。
下面是上述方法的实现:
C++
// C++ program for the above approach
#include
using namespace std;
// Function to find the smallest
// array that can be removed from
// the ends of an array to obtain sum K
void minSizeArr(int A[], int N, int K)
{
int sum = 0;
// Sum of complete array
for (int i = 0; i < N; i++)
sum += A[i];
// If given number is greater
// than sum of the array
if (K > sum) {
cout << -1;
return;
}
// If number is equal to
// the sum of array
if (K == sum) {
for (int i = 0; i < N; i++) {
cout << A[i] << " ";
}
return;
}
// tar is sum of middle subarray
int tar = sum - K;
// Find the longest subarray
// with sum equal to tar
unordered_map um;
um[0] = -1;
int left, right;
int cur = 0, maxi = -1;
for (int i = 0; i < N; i++) {
cur += A[i];
if (um.find(cur - tar) != um.end()
&& i - um[cur - tar] > maxi) {
maxi = i - um[cur - tar];
right = i;
left = um[cur - tar];
}
if (um.find(cur) == um.end())
um[cur] = i;
}
// If there is no subarray with
// sum equal to tar
if (maxi == -1)
cout << -1;
else {
for (int i = 0; i <= left; i++)
cout << A[i] << " ";
for (int i = 0; i < right; i++)
cout << A[N - i - 1] << " ";
}
}
// Driver Code
int main()
{
int N = 7;
// Given Array
int A[] = { 3, 2, 1, 1, 1, 1, 3 };
// Given target sum
int K = 10;
minSizeArr(A, N, K);
return 0;
}
Java
// Java program for the above approach
import java.io.*;
import java.util.*;
class GFG {
// Function to find the smallest
// array that can be removed from
// the ends of an array to obtain sum K
static void minSizeArr(int A[], int N, int K)
{
int sum = 0;
// Sum of complete array
for (int i = 0; i < N; i++)
sum += A[i];
// If given number is greater
// than sum of the array
if (K > sum) {
System.out.print(-1);
return;
}
// If number is equal to
// the sum of array
if (K == sum) {
for (int i = 0; i < N; i++) {
System.out.print(A[i] + " ");
}
return;
}
// tar is sum of middle subarray
int tar = sum - K;
// Find the longest subarray
// with sum equal to tar
HashMap um = new HashMap();
um.put(0, -1);
int left = 0, right = 0;
int cur = 0, maxi = -1;
for (int i = 0; i < N; i++) {
cur += A[i];
if (um.containsKey(cur - tar)
&& i - um.get(cur - tar) > maxi) {
maxi = i - um.get(cur - tar);
right = i;
left = um.get(cur - tar);
}
if (!um.containsKey(cur))
um.put(cur, i);
}
// If there is no subarray with
// sum equal to tar
if (maxi == -1)
System.out.println(-1);
else {
for (int i = 0; i <= left; i++)
System.out.print(A[i] + " ");
for (int i = 0; i < right; i++)
System.out.print(A[N - i - 1] + " ");
}
}
// Driver Code
public static void main (String[] args) {
int N = 7;
// Given Array
int A[] = { 3, 2, 1, 1, 1, 1, 3 };
// Given target sum
int K = 10;
minSizeArr(A, N, K);
}
}
// This code is contributed by Dharanendra L V.
蟒蛇3
# python 3 program for the above approach
# Function to find the smallest
# array that can be removed from
# the ends of an array to obtain sum K
def minSizeArr(A, N, K):
sum = 0
# Sum of complete array
for i in range(N):
sum += A[i]
# If given number is greater
# than sum of the array
if (K > sum):
print(-1);
return
# If number is equal to
# the sum of array
if (K == sum):
for i in range(N):
print(A[i],end = " ")
return
# tar is sum of middle subarray
tar = sum - K
# Find the longest subarray
# with sum equal to tar
um = {}
um[0] = -1
left = 0
right = 0
cur = 0
maxi = -1
for i in range(N):
cur += A[i]
if((cur - tar) in um and (i - um[cur - tar]) > maxi):
maxi = i - um[cur - tar]
right = i
left = um[cur - tar]
if(cur not in um):
um[cur] = i
# If there is no subarray with
# sum equal to tar
if (maxi == -1):
print(-1)
else:
for i in range(left+1):
print(A[i], end = " ")
for i in range(right):
print(A[N - i - 1], end = " ")
# Driver Code
if __name__ == '__main__':
N = 7
# Given Array
A = [3, 2, 1, 1, 1, 1, 3]
# Given target sum
K = 10
minSizeArr(A, N, K)
# This code is contributed by SURENDRA_GANGWAR.
C#
// C# program for
// the above approach
using System;
using System.Collections.Generic;
class GFG{
// Function to find the smallest
// array that can be removed from
// the ends of an array to obtain sum K
static void minSizeArr(int[] A, int N, int K)
{
int sum = 0;
// Sum of complete array
for(int i = 0; i < N; i++)
sum += A[i];
// If given number is greater
// than sum of the array
if (K > sum)
{
Console.WriteLine(-1);
return;
}
// If number is equal to
// the sum of array
if (K == sum)
{
for(int i = 0; i < N; i++)
{
Console.Write(A[i] + " ");
}
return;
}
// tar is sum of middle subarray
int tar = sum - K;
// Find the longest subarray
// with sum equal to tar
Dictionary um = new Dictionary();
um[0] = -1;
int left = 0, right = 0;
int cur = 0, maxi = -1;
for(int i = 0; i < N; i++)
{
cur += A[i];
if (um.ContainsKey(cur - tar) &&
i - um[cur - tar] > maxi)
{
maxi = i - um[cur - tar];
right = i;
left = um[cur - tar];
}
if (!um.ContainsKey(cur))
um[cur] = i;
}
// If there is no subarray with
// sum equal to tar
if (maxi == -1)
Console.Write(-1);
else
{
for(int i = 0; i <= left; i++)
Console.Write(A[i] + " ");
for(int i = 0; i < right; i++)
Console.Write(A[N - i - 1] + " ");
}
}
// Driver code
static public void Main()
{
int N = 7;
// Given Array
int[] A = { 3, 2, 1, 1, 1, 1, 3 };
// Given target sum
int K = 10;
minSizeArr(A, N, K);
}
}
// This code is contributed by offbeat
Javascript
输出:
3 2 3 1 1
时间复杂度: O(N)
辅助空间: O(N)
如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程和学生竞争性编程现场课程。