繁体   English   中英

修改数组以最小化差异

[英]Modify the array to minimize the difference

您将获得n值的数组A和值k 您必须增加或减少A的每个元素k并且必须对每个元素只执行一次。 目标是最小化结果数组A的最大元素和最小元素之间的差异(修改后)并输出该差异。

例如, A=[1,7]k=4 ,我们需要将A修改为[5,3] ,然后差值为2 ,这是我们可以达到的最小差异。

任何人都可以帮我解决这个问题吗?

这是一种思考它的方法(想象一个排序的数组, xa[i] + kya[i] - k

x
  x
      x
           x
y              
  y             x[i](min?)
      y                   x
           y                  x[n-1]
                y[i](min?)     
                          y   
                              y 

如果您选择y[i]作为最小值,您的最​​大选择将是:

max( y[0], x[i + 1] )

如果你选择x[i]作为最小值...哦,你不能因为任何a[j] ± k, j > i必须在这个排序的排列中更小。

如果选择x[n-1]作为最小值,则最大值的选择将是所有min(x[j],y[j]) where both x[j] and y[j] are greater than or equal to x[n-1] (or just x[j] if y[j] < x[n-1])最大值min(x[j],y[j]) where both x[j] and y[j] are greater than or equal to x[n-1] (or just x[j] if y[j] < x[n-1])

如果选择y[0]作为最小值,则选择最大值为max(x[j]) ,前提是所有x[j]都大于或等于y[0]

这是一个订单为O(n*log(n))

public class MinDiff 
{
    public static void main(String[] args) 
    {
        int A[] = {1,7};
        int k = 4;
        System.out.println("Input a:=" + Arrays.toString(A) + ", k:=" + k);
        find(A, k);
        System.out.println("Output a´:=" + Arrays.toString(A));
    }

    private static void find(int a[], int k) 
    {       
        Arrays.sort(a);

        int n = a.length;
        if (k > a[n - 1] - a[0])
        {
            for (int i = 0; i < n; i++)
                a[i] += k;
            return;
        }

        a[0] = a[0] + k;
        a[n - 1] = a[n - 1] - k;

        int max = Math.max(a[0], a[n - 1]);
        int min = Math.min(a[0], a[n - 1]);

        for (int index = 1; index < n - 1; index++) 
        {
            if (a[index] < min)
                a[index] += k;
            else if (a[index] > max)
                a[index] -= k;
            else if ((a[index] - min) > (max - a[index]))
                a[index] -= k;
            else
                a[index] += k;

            max = Math.max(a[index], max);
            min = Math.min(a[index], min);
        }
    }
}

输入: a:= [1,7],k:= 4

输出: a':= [5,3]

我在C ++中的递归动态编程解决方案。时间复杂度为O(N3) -

    #include <iostream>
    #include <vector>
    #include <map>
    #include <cmath>
    #include <limits>

    using namespace std;

    vector <int> v;
    map < pair <int, pair <int,int> >, int > mp;

    int k, n;

    int solve(int index, int minimum, int maximum)
    {
            if(index == n)
                    return maximum - minimum;
            pair <int, pair <int,int> > p = pair <int, pair <int,int> > (index, pair <int,int> (minimum, maximum));
            if(mp.find(p) != mp.end())
                    return mp[p];
            int x = v[index] - k, y = v[index] + k;
            return mp[p] = min(solve(index + 1, min(x, minimum), max(x, maximum)), solve(index + 1, min(y, minimum), max(y, maximum)));
    }

    int main()
    {
            int p = std::numeric_limits<int>::max();
            int q = std::numeric_limits<int>::min();
            cin >> k >> n;
            int x;
            for(int i = 0;i < n;i++)
            {
                    cin >> x;
                    v.push_back(x);
            }
            cout << solve(0, p, q) << endl;
            return 0;
    }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM