题目来源于力扣(LeetCode)
一、题目
题目相关标签:数组
提示:
1 <= A.length <= 50000
-100000 <= A[i] <= 100000
二、解题思路
2.1 线性扫描法
-
计算得到数组元素末尾与首位的差 diff,差为 0 时,则数组中元素全为重复元素满足单调,差小于 0 时,数组中元素全为非递增元素满足单调,差大于 0 时,数组中元素全为非递减元素满足单调
-
遍历数组(从第 1 项开始),计算得到每一个元素与前一元素的差
-
若差大于 0 而 diff 小于 0 时,说明出现了递增与递减,不满足单调条件
-
若差小于 0 而 diff 大于 0 时,说明出现了递减与递增,不满足单调条件
-
若差不等于 0 而 diff 等于 0 时,说明出现了递增与递减,不满足单调条件
2.2 两次遍历法
-
定义两个方法,分别遍历数组,判断数组元素是否为非递增与非递减
-
两者满足其一即可返回 true
三、代码实现
3.1 线性扫描法
public static boolean isMonotonic(int[] A) {
if (A.length <= 2) {
return true;
}
// 标准差,最后一项与第一项的差,为 0 说明为非递增非递减序列,大于 0 为递增序列,小于 0 为递减序列
int diff = A[A.length - 1] - A[0];
for (int i = 1; i < A.length; i++) {
int j = A[i] - A[i - 1];
if (j > 0 && diff < 0) {
// 两数差大于 0 ,且标准差小于 0 的情况
return false;
} else if (j < 0 && diff > 0) {
// 两数差小于 0,且标准差大于 0 的情况
return false;
} else if (j != 0 && diff == 0) {
// 两数差不等于 0,且标准差等于 0 的情况
return false;
}
}
return true;
}
3.2 两次遍历法
public static boolean isMonotonic(int[] A) {
// 两者都不满足,则一定为非递增,非递减,以及重复序列
return increasing(A) || decreasing(A);
}
// 判断数组元素是否为递增或重复
public static boolean increasing(int[] nums) {
for (int i = 0; i < nums.length - 1; i++) {
// 递减时,返回 false
if (nums[i] > nums[i + 1]) {
return false;
}
}
return true;
}
// 判断数组元素是否为递减或重复
public static boolean decreasing(int[] nums) {
for (int i = 0; i < nums.length - 1; i++) {
// 递增时,返回 false
if (nums[i] < nums[i + 1]) {
return false;
}
}
return true;
}
四、执行用时
4.1 线性扫描法
4.2 两次遍历法
五、部分测试用例
public static void main(String[] args) {
int[] nums = {1, 2, 2, 3}; // output: true
// int[] nums = {6, 5, 4, 4}; // output: true
// int[] nums = {1, 3, 2}; // output: false
// int[] nums = {1, 2, 4, 5}; // output: true
// int[] nums = {1, 1, 1}; // output: true
boolean result = isMonotonic(nums);
System.out.println(result);
}