每日leetcode(昨天赶飞机没做,今天补)
896. 单调数列 - 力扣(LeetCode)
题目
如果数组是单调递增或单调递减的,那么它是 单调 的。
如果对于所有 i <= j
,nums[i] <= nums[j]
,那么数组 nums
是单调递增的。 如果对于所有 i <= j
,nums[i] >= nums[j]
,那么数组 nums
是单调递减的。
当给定的数组 nums
是单调数组时返回 true
,否则返回 false
。
示例 1:
输入:nums = [1,2,2,3]
输出:true
示例 2:
输入:nums = [6,5,4,4]
输出:true
示例 3:
输入:nums = [1,3,2]
输出:false
提示:
1 <= nums.length <= 105
-105 <= nums[i] <= 105
思路
- 先找到有增减趋势的第一个相邻元素,然后记录其增减趋势,每次乘下一相邻元素的差值,只有相邻两对差值相反的时候相乘才会小于0,这个时候就返回false即可。
- 若遍历完没有被打断,即返回true。
代码实现
class Solution {
public:bool isMonotonic(vector<int>& nums) {int n = nums.size(), i = 1;long long diff;if(n <= 2) return true;while(nums[i]-nums[i-1]==0) {++i;if(i == n) return true;}diff = nums[i]-nums[i-1];for(i = i+1; i < n; ++i) {if(diff * (nums[i] - nums[i-1]) < 0) return false; }return true;}
};
复杂度分析
- 时间复杂度:要分别访问每个元素两次——O(n)。
- 空间复杂度:O(1)。
题解与反思
- 我的实现是非常丑陋的,没有考虑到数据溢出的问题,其实不应该相乘,因为结果可能会非常大,那么能接受的数据就不能非常大,这将会是非常有局限性的,所以最好的选择还是设计一个标记,再进行判断。
- 另外,差值其实也可以不用计算,直接判断相邻两元素的大小关系即可,还能省一个变量。
-
class Solution { public:bool isMonotonic(vector<int>& nums) {int n = nums.size(), flag = 0, diff;if(n < 3) return true;for(int i = 1; i < n; ++i) {if(nums[i] == nums[i-1]) continue;if(nums[i] < nums[i-1]) {if(flag == 0) flag = -1;if(flag == 1) return false;}else {if(flag == 0) flag = 1;if(flag == -1) return false; }}return true;} };