[英]Modify the array to minimize the difference
您将获得n
值的数组A
和值k
。 您必须增加或减少A
的每个元素k
并且必须对每个元素只执行一次。 目标是最小化结果数组A
的最大元素和最小元素之间的差异(修改后)并输出该差异。
例如, A=[1,7]
, k=4
,我们需要将A
修改为[5,3]
,然后差值为2
,这是我们可以达到的最小差异。
任何人都可以帮我解决这个问题吗?
这是一种思考它的方法(想象一个排序的数组, x
是a[i] + k
而y
是a[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.