题目:在数组中,数字减去它右边的数字得到一个数对之差。求所有数对之差的最大值。例如在数组{2, 4, 1, 16, 7, 5, 11, 9}中,数对之差的最大值是11,是16减去5的结果。
1:解法1:直接计算,时间复杂度为o(n^2)
public static int getMax1(int[] a) {
int max = a[0] - a[1];
for (int i = 0; i < a.length - 1; i++) {
for (int j = i + 1; j < a.length; j++) {
if (a[i] - a[j] > max) {
max = a[i] - a[j];
}
}
}
return max;
}
2:转化为求子数组的最大和值
/**
*
* 时间复杂度为o(n) 如果输入一个长度为n的数组numbers,我们先构建一个长度为n-1的辅助数组diff,
* 并且diff[i]等于numbers[i]-numbers[i+1](0<=i<n-1)。
* 分析到这里,我们发现原始数组中最大的数对之差(即numbers[i] – numbers[j
* +1])其实是辅助数组diff中最大的连续子数组之和。
*
* @param a
* @return
*/
public static int getMax2(int[] a) {
// 将该问题转化为:求子数组的最大和
int[] arr = new int[a.length - 1];
for (int i = 0; i < a.length - 1; i++) {
arr[i] = a[i] - a[i + 1];
}
// 求子数组的最大和
int result = 0;
int temp = result;
for (int i = 0; i < arr.length; i++) {
temp += arr[i];
if (temp < 0) {
temp = 0;
}
if (temp > result) {
result = temp;
}
}
if (result == 0) {
int max = a[0];
for (int i = 1; i < arr.length; i++) {
if (arr[i] > max) {
max = array[i];
}
}
}
return result;
}
3:动态规划求解:
遍历数组,则数对只差的最大值为:前部元素的最大值(max)-当前值,并取得最大值即可。
们定义diff[i]是以数组中第i个数字为减数的所有数对之差的最大值。也就是说对于任意h(h <
* i),diff[i]≥number[h]-number[i]。diff[i](0≤i<n)的最大值就是整个数组最大的数对之差。
public static int getMax3(int[] a) {
if (a == null || a.length < 2) {
return 0;
}
int max = a[0];
int maxDiff = max - a[1];
for (int i = 2; i < a.length; i++) {
if (a[i - 1] > max) {
max = a[i - 1];
}
int currentDiff = max - a[i];
if (currentDiff > maxDiff) {
maxDiff = currentDiff;
}
}
return maxDiff;
}
总结:
1:解法1:时间复杂度为o(n^2);
2:解法2:时间复杂度为o(n),但是却需要一个辅助数组,空间复杂度为o(n);
3: 解法3:没有空间开销,时间复杂度为o(n);
参考:http://zhedahht.blog.163.com/blog/static/2541117420116135376632/