• 【LeetCode】775. 全局倒置与局部倒置


    题目描述

    给你一个长度为 n 的整数数组 nums ,表示由范围 [0, n - 1] 内所有整数组成的一个排列。
    全局倒置 的数目等于满足下述条件不同下标对 (i, j) 的数目:
    0 <= i < j < n
    nums[i] > nums[j]
    局部倒置 的数目等于满足下述条件的下标 i 的数目:
    0 <= i < n - 1
    nums[i] > nums[i + 1]
    当数组 nums 中 全局倒置 的数量等于 局部倒置 的数量时,返回 true ;否则,返回 false 。

    示例 1:

    输入:nums = [1,0,2]
    输出:true
    解释:有 1 个全局倒置,和 1 个局部倒置。

    示例 2:

    输入:nums = [1,2,0]
    输出:false
    解释:有 2 个全局倒置,和 1 个局部倒置。

    提示:

    n == nums.length
    1 <= n <= 105
    0 <= nums[i] < n
    nums 中的所有整数 互不相同
    nums 是范围 [0, n - 1] 内所有数字组成的一个排列

    方法一:维护最小后缀值

    class Solution {
    public:
        bool isIdealPermutation(vector<int>& nums) {
            int len=nums.size();
            int minSuffix = nums[len-1];
            for(int i=len-3; i>=0; i--){
                if(nums[i]>minSuffix){
                    return false;
                }
                minSuffix = min(minSuffix, nums[i+1]);
            }
            return true;
        }
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    方法二:偏移差值判断

    class Solution {
    public:
        bool isIdealPermutation(vector<int>& nums) {
            int len=nums.size();
            for(int i=0; i<len; i++){
                if(abs(nums[i] - i)> 1){
                    return false;
                }
            }
            return true;
        }
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    心得

    • 这道题我一开始用了两个for循环,设置了两个变量分别记录全局倒置和局部倒置的数目,最后判断两者是否相等,但是这个方法的时间复杂度已经达到了O(n2),有一些测试点因为超时而过不去。
    • 思想
      1.由于局部倒置一定是全局倒置,而全局倒置不一定是局部倒置,因此这道题可以转换成「 寻找全局倒置且非局部倒置」,如果出现这种情况,则返回false,否则返回true。
      非局部倒置指的是,nums[i] > nums[j] 且 i < j+1;
      2.此外,只能设置一个for循环才不会超时。
    • 方法一:维护最小后缀值
      对于每个nums[i],判断是否存在j(j+1>i)使得nums[i] > nums[j],可以转换为检查nums[i] > min(nums[i+2], …, nums[n-1]) 。因此,本方法维护一个minSuffix=min(nums[i+2], …, nums[n-1]),存储当前nums[i+2]及其之后的最小值。
      为了提高代码效率,从nums[n-3]开始倒序往前遍历,如果出现了非局部倒置,就可以做出判断。
    • 方法二:偏移差值判断
      由于题目中存在一个关键条件:「长度为 n 的整数数组 nums ,表示由范围 [0, n - 1] 内所有整数组成的一个排列」,因此可以通过nums[i] - i计算出i位置的元素与有序后的位置之间的差值
      当差值>1时,说明了元素所在位置偏差>1,也就是出现了非全局倒置的情况。在这里插入图片描述
  • 相关阅读:
    系统集成|第二十一章(笔记)
    redis集群系列二
    哪个品种能够叫板白银现货t+d?
    yarn的安装与配置(Windows/macOS)
    第十一章:Java对象内存布局和对象头
    es6新增-Generator(异步编程的解决方案2)
    08Java算术运算符/除法与取模/隐式转换/强制转换/字符串相加/字符相加
    【springboot】通过拦截器全局监听请求
    (01)ORB-SLAM2源码无死角解析-(59) 闭环线程→闭环矫正: CorrectLoop→位姿传播,地图点矫正
    单机版redis的安装
  • 原文地址:https://blog.csdn.net/weixin_43894455/article/details/127880327