📜  绝对和最接近K的子数组

📅  最后修改于: 2021-05-04 17:03:48             🧑  作者: Mango

给定一个由n个元素组成的数组和一个整数K,任务是找到最小值为|| a [i] + a [i + 1] +……的子数组。 a [j] | – K | 。换句话说,找到元素的总和与K的最小偏差的连续子数组或绝对和最接近K的子数组。

例子

一个简单的方法是检查每个连续子数组的总和是否与K相差。

下面是上述方法的实现:

C++
// C++ code to find sub-array whose
// sum shows the minimum deviation
#include 
using namespace std;
 
int* getSubArray(int arr[], int n, int K)
{
    int i = -1;
    int j = -1;
    int currSum = 0;
       
    // Starting index, ending index,
    // Deviation
    int* result = new int[3]{ i, j,
                              abs(K -
                              abs(currSum)) };
       
    // Iterate i and j to get all subarrays
    for(i = 0; i < n; i++)
    {
        currSum = 0;
           
        for(j = i; j < n; j++)
        {
            currSum += arr[j];
            int currDev = abs(K - abs(currSum));
               
            // Found sub-array with less sum
            if (currDev < result[2])
            {
                result[0] = i;
                result[1] = j;
                result[2] = currDev;
            }
               
            // Exactly same sum
            if (currDev == 0)
                return result;
        }
    }
    return result;
}
 
// Driver code  
int main()
{
    int arr[8] = { 15, -3, 5, 2, 7, 6, 34, -6 };
    int n = sizeof(arr) / sizeof(arr[0]);
    int K = 50;
           
    // Array to store return values
    int* ans = getSubArray(arr, n, K);
           
    if (ans[0] == -1)
    {
        cout << "The empty array shows "
             << "minimum Deviation";
    }
    else
    {
        for(int i = ans[0]; i <= ans[1]; i++)
            cout << arr[i] << " ";
    }
    return 0;
}
 
// This code is contributed by divyeshrabadiya07


Java
// Java code to find sub-array whose
// sum shows the minimum deviation
class GFG{
     
public static int[] getSubArray(int[] arr,
                                int n,int K)
{
    int i = -1;
    int j = -1;
    int currSum = 0;
     
    // Starting index, ending index, Deviation
    int [] result = { i, j,
                      Math.abs(K -
                      Math.abs(currSum)) };
     
    // Iterate i and j to get all subarrays
    for(i = 0; i < n; i++)
    {
        currSum = 0;
         
        for(j = i; j < n; j++)
        {
            currSum += arr[j];
            int currDev = Math.abs(K -
                          Math.abs(currSum));
             
            // Found sub-array with less sum
            if(currDev < result[2])
            {
                result[0] = i;
                result[1] = j;
                result[2] = currDev;
            }
             
            // Exactly same sum
            if(currDev == 0)
                return result;
        }
    }
    return result;
}
 
// Driver Code
public static void main(String[] args)
{
    int[] arr = { 15, -3, 5, 2, 7, 6, 34, -6 };
    int n = arr.length;
    int K = 50;
         
    // Array to store return values
    int[] ans = getSubArray(arr, n, K);
         
    if(ans[0] == -1)
    {
        System.out.println("The empty array " +
                           "shows minimum Deviation");
    }
    else
    {
        for(int i = ans[0]; i <= ans[1]; i++)
            System.out.print(arr[i] + " ");
    }
}
}
 
// This code is contributed by dadimadhav


Python
# Python Code to find sub-array whose
# sum shows the minimum deviation
 
def getSubArray(arr, n, K):
    i = -1
    j = -1
    currSum = 0
    # starting index, ending index, Deviation
    result = [i, j, abs(K-abs(currSum))]
     
    # iterate i and j to get all subarrays
    for i in range(0, n):
         
        currSum = 0
         
        for j in range(i, n):
            currSum += arr[j]
            currDev = abs(K-abs(currSum))
             
            # found sub-array with less sum
            if (currDev < result[2]):
                result = [i, j, currDev]
                 
            # exactly same sum
            if (currDev == 0):
                return result
    return result
     
# Driver Code
def main():
    arr = [15, -3, 5, 2, 7, 6, 34, -6]
     
    n = len(arr)
     
    K = 50
     
    [i, j, minDev] = getSubArray(arr, n, K)
     
    if(i ==-1):
        print("The empty array shows minimum Deviation")
        return 0
     
    for i in range(i, j + 1):
        print arr[i],
     
     
main()


C#
// C# code to find sub-array whose
// sum shows the minimum deviation
using System;
 
class GFG{
     
public static int[] getSubArray(int[] arr,
                                int n, int K)
{
    int i = -1;
    int j = -1;
    int currSum = 0;
     
    // Starting index, ending index, Deviation
    int [] result = { i, j,
                      Math.Abs(K -
                      Math.Abs(currSum)) };
     
    // Iterate i and j to get all subarrays
    for(i = 0; i < n; i++)
    {
        currSum = 0;
         
        for(j = i; j < n; j++)
        {
            currSum += arr[j];
            int currDev = Math.Abs(K -
                          Math.Abs(currSum));
             
            // Found sub-array with less sum
            if (currDev < result[2])
            {
                result[0] = i;
                result[1] = j;
                result[2] = currDev;
            }
             
            // Exactly same sum
            if (currDev == 0)
                return result;
        }
    }
    return result;
}
 
// Driver Code
public static void Main(string[] args)
{
    int[] arr = { 15, -3, 5, 2, 7, 6, 34, -6 };
    int n = arr.Length;
    int K = 50;
         
    // Array to store return values
    int[] ans = getSubArray(arr, n, K);
         
    if (ans[0] == -1)
    {
        Console.Write("The empty array " +
                      "shows minimum Deviation");
    }
    else
    {
        for(int i = ans[0]; i <= ans[1]; i++)
            Console.Write(arr[i] + " ");
    }
}
}
 
// This code is contributed by rutvik_56


C++
// C++ code to find non-negative sub-array
// whose sum shows minimum deviation. This
// works only if all elements in array are
// non-negative
#include 
using namespace std;
 
struct Pair
{
    int f, s, t;
 
    Pair(int f, int s, int t)
    {
        this->f = f;
        this->s = s;
        this->t = t;
    }
};
 
// Function to return the index
Pair* getSubArray(int *arr, int n, int K)
{
    int currSum = 0;
    int prevDif = 0;
    int currDif = 0;
     
    Pair *result = new Pair(
        -1, -1, abs(K - abs(currSum)));
    Pair *resultTmp = result;
    int i = 0;
    int j = 0;
     
    while (i<= j && jt) < abs(result->t))
        {
             
            // Check if lesser deviation found
            result = resultTmp;
        }
    }
    return result;
}
 
// Driver Code
int main()
{
    int arr[] = { 15, -3, 5, 2, 7, 6, 34, -6 };
     
    int n = sizeof(arr) / sizeof(arr[0]);
     
    int K = 50;
     
    Pair *tmp = getSubArray(arr, n, K);
    int i = tmp->f;
    int j = tmp->s;
    int minDev = tmp->t;
     
    if (i == -1)
    {
        cout << "The empty array shows minimum Deviation"
             << endl;
        return 0;
    }
     
    for(int k = i + 1; k < j + 1; k++)
    {
        cout << arr[k] << " ";
    }
     
    return 0;
}
 
// This code is contributed by pratham76


Python
# Python Code to find non-negative
# sub-array whose sum shows minimum deviation
# This works only if all elements
# in array are non-negative
 
 
# function to return the index
def getSubArray(arr, n, K):
    currSum = 0
    prevDif = 0
    currDif = 0
    result = [-1, -1, abs(K-abs(currSum))]
    resultTmp = result
    i = 0
    j = 0
     
    while(i<= j and j


输出:
-3 5 2 7 6 34

时间复杂度: O(N ^ 2)

高效的方法:如果数组仅由非负整数组成,请使用滑动窗口技术来缩短每次迭代中求和的计算时间。滑动窗口技术通过使用先前的子数组和计算新的子数组和来降低复杂度。增加右索引,直到差(K-sum)大于零。考虑第一个具有负数(K-sum)的子数组,下一个子数组的左索引= i + 1(其中i是当前的右索引)。

下面是上述方法的实现:

C++

// C++ code to find non-negative sub-array
// whose sum shows minimum deviation. This
// works only if all elements in array are
// non-negative
#include 
using namespace std;
 
struct Pair
{
    int f, s, t;
 
    Pair(int f, int s, int t)
    {
        this->f = f;
        this->s = s;
        this->t = t;
    }
};
 
// Function to return the index
Pair* getSubArray(int *arr, int n, int K)
{
    int currSum = 0;
    int prevDif = 0;
    int currDif = 0;
     
    Pair *result = new Pair(
        -1, -1, abs(K - abs(currSum)));
    Pair *resultTmp = result;
    int i = 0;
    int j = 0;
     
    while (i<= j && jt) < abs(result->t))
        {
             
            // Check if lesser deviation found
            result = resultTmp;
        }
    }
    return result;
}
 
// Driver Code
int main()
{
    int arr[] = { 15, -3, 5, 2, 7, 6, 34, -6 };
     
    int n = sizeof(arr) / sizeof(arr[0]);
     
    int K = 50;
     
    Pair *tmp = getSubArray(arr, n, K);
    int i = tmp->f;
    int j = tmp->s;
    int minDev = tmp->t;
     
    if (i == -1)
    {
        cout << "The empty array shows minimum Deviation"
             << endl;
        return 0;
    }
     
    for(int k = i + 1; k < j + 1; k++)
    {
        cout << arr[k] << " ";
    }
     
    return 0;
}
 
// This code is contributed by pratham76

Python

# Python Code to find non-negative
# sub-array whose sum shows minimum deviation
# This works only if all elements
# in array are non-negative
 
 
# function to return the index
def getSubArray(arr, n, K):
    currSum = 0
    prevDif = 0
    currDif = 0
    result = [-1, -1, abs(K-abs(currSum))]
    resultTmp = result
    i = 0
    j = 0
     
    while(i<= j and j
输出
-3 5 2 7 6 34

时间复杂度: O(N)