LeetCode 记录-775. 全局倒置与局部倒置
我的解法
思路
我们可以看出一个局部倒置一定是一个全局倒置,所以我们只需要判断是否存在一个不是局部倒置的全局倒置,就是判断对于每一个 i(),是否存在一个 j()使得满足。当找到一个满足条件的下标对时,直接返回 false,当遍历结束,返回 true。
这个思路的时间复杂度比较高,本来觉得可以使用单调栈的思路解决问题,但想了一下好像不行。
代码
/**
* @param {number[]} nums
* @return {boolean}
*/
var isIdealPermutation = function (nums) {
for (let i = 0; i < nums.length - 2; i++) {
let j = i + 2;
while (j < nums.length) {
if (nums[i] > nums[j]) {
return false;
}
j++;
}
}
return true;
};
复杂度分析(自我分析,不一定对)
时间复杂度
,n 为 nums 数组的长度。在最差情况下,全局倒置和局部倒置个数一样,需要全部遍历一边。
空间复杂度
官方解法 1: 维护后缀最小值
思路
这题的思路前半部分和我的解法类似,但官方在寻找不是局部倒置的全局倒置时,是从后往前寻找的(从 开始),寻找的同时维护了一个后缀数组中的最小值 minSuffix(后缀数组的下标范围为),因为只需要比较 nums[i]和 minSuffix 就可以判断是否存在这样的全局倒置了。最巧妙的地方是,因为从后往前寻找,所以每次只需要比较 minSuffix 和新添加进后缀数组的值,这样的话,总体的时间复杂度就降低到了。
代码
/**
* @param {number[]} nums
* @return {boolean}
*/
var isIdealPermutation = function (nums) {
const len = nums.length;
let minSuffix = nums[len - 1];
for (let i = len - 3; i >= 0; i--) {
if (nums[i] > minSuffix) {
return false;
}
minSuffix = Math.min(minSuffix, nums[i + 1]);
}
return true;
};
复杂度分析
时间复杂度
,其中 n 是 nums 的长度。
空间复杂度
,只使用到常数个变量空间。
官方解法 2: 归纳证明
思路
通过归纳证明的方式来判断,放个截图,就不详细看啦。