题目跳转https://www.nowcoder.com/practice/a01abbdc52ba4d5f8777fb5dae91b204?tpId=128&tqId=33768&ru=/exam/oj
题目描述:
有一个长为 n 的数组 A ,求满足 0 ≤ a ≤ b < n 的 A[b] - A[a] 的最大值。
给定数组 A 及它的大小 n ,请返回最大差值。
数据范围: ,数组中的值满足
示例1
输入:[5,1],2
复制返回值:0
示例2
输入:[5,6],2
复制返回值:1
题干解析:
从题目中我们可以得出以下几点结论:
- 从给定的 数组A 中求出最大差值;
- 数组的顺序不能改变;
- 结果必须大于等于0;
- 必须是后面的数减前面的数。
暴力求解:
读完题目后我们可以很容易的写出暴力解法:
利用两个for()循环把每一个数都试一遍然后返回其中的最大值。
代码展示:
public int getDis (int[] A, int n) { int max = 0; for (int i = 0; i < n; i++){ for (int j = i+1; j < n; j++){ if (A[j] - A[i] > max){ max = A[j] - A[i]; } } } return max; }
但是当我们写完之后我们自己也一定会觉得这段代码的时间复杂度太大了可能会挂,运行之后也确实挂了。
优化:
根据题目描述我们可以先简单的画一张折线图每一个点都是一个数据:
据图可知我们需要返回的是 b1,b2,b3,b4,b5,b6 中的最大值 。
此时我们我们就可以:
- 定义一个 max 变量用来存储已遍历过的数最大差值;
- 定义一个变量 a 用来存储已遍历过的数中的最小值;
- 用一个 for()循环 来对 数组A 进行遍历,然后不断更新 max 和 a 的值。
代码展示:
public int getDis (int[] A, int n) { int max = 0; int a = 0; for (int i = 1; i < n; i++){ if (A[i] - A[a] > max){ max = A[i] - A[a]; } if (A[i] < A[a]){ a = i; } } return max; }
此时代码的时间复杂度被压缩到了O(n),所以只要思路正确就一定会通过。