775. Global and Local Inversions**

本文探讨LeetCode上编号为775的问题——全局与局部倒置,提供两种C++实现方案,包括通过排序比较和直接遍历数组的方法,来判断全局倒置与局部倒置数量是否相等。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

775. Global and Local Inversions**

https://leetcode.com/problems/global-and-local-inversions/

题目描述

We have some permutation A of [0, 1, ..., N - 1], where N is the length of A.

The number of (global) inversions is the number of i < j with 0 <= i < j < N and A[i] > A[j].

The number of local inversions is the number of i with 0 <= i < N and A[i] > A[i+1].

Return true if and only if the number of global inversions is equal to the number of local inversions.

Example 1:

Input: A = [1,0,2]
Output: true
Explanation: There is 1 global inversion, and 1 local inversion.

Example 2:

Input: A = [1,2,0]
Output: false
Explanation: There are 2 global inversions, and 1 local inversion.

Note:

  • A will be a permutation of [0, 1, ..., A.length - 1].
  • A will have length in range [1, 5000].
  • The time limit for this problem has been reduced.

C++ 实现 1

这道题只需要判断 local inversions 和 global inversions 是否完全相等, 那么就需要考虑 “完全相等” 的条件到底是什么. 首先, 对数组进行排序, 比如 [0, 1, 2, 3, 4], 如果一个序列完全有序, local inversions 和 global inversions 均为 0. 要出现 local inversions 和 global inversions 完全相等的情况, 只能是两个相邻的数进行了交换才行, 比如 0 和 1 交换, 数组变成了 [1, 0, 2, 3, 4]. 如果 0 和 2 交换, 数组变成 [2, 1, 0, 3, 4], 此时 local inversion 为 1, global inversions 为 2.

假设排序后的数组为 B,当访问到 A[i], 如果 A[i] != B[i], 那么判断是否 A[i+ 1] == B[i] && A[i] == B[i + 1] 成立.

class Solution {
public:
    bool isIdealPermutation(vector<int>& A) {
        auto B = A;
        std::sort(B.begin(), B.end());
        for (int i = 0; i < A.size() - 1; ++ i) {
            if (A[i] != B[i]) {
                if (A[i + 1] == B[i] && B[i + 1] == A[i])
                    ++ i;
                else
                    return false;
            }
        }
        return true;
    }
};

C++ 实现 2

由于 A[0, ..., N - 1] 的组合, 因此一次访问 [0, ... N - 1] 相当于访问排序后的数组 B 了, 就不用像 C++ 实现 1 那样申请额外的空间.

class Solution {
public:
    bool isIdealPermutation(vector<int>& A) {
        int n = A.size();
        for (int i = 0; i < n - 1; i++) {
            if (A[i] != i) {
                if (A[i+1] != i || A[i] != i+1) return false;
                i++;
            }
        }
        return true;
    }
};
在给定数组中计算逆序对的数量是一个经典的计算机科学问题,通常采用哈希表(也称为散列表)的数据结构来解决。算法的基本步骤如下: 1. **排序数组**:首先对数组进行排序,这样可以使得相邻元素之间的大小关系变得明显。 2. **遍历数组**:从排序后的数组的第一个元素开始,对于每个元素,检查它之后的所有元素,如果当前元素大于后续元素,就找到了一个逆序对。由于我们只需要计数,所以不需要记录每一个具体的逆序对,只统计遇到的情况即可。 3. **双指针法**:为了提高效率,可以用两个指针,一个固定在已排序部分的最后一个元素,另一个从后向前移动。这样避免了重复计算已经处理过的元素。 4. **哈希表优化**:通过哈希表存储每个位置元素及其索引,当找到一个新的逆序对时,可以在常数时间内查找到前一个元素的位置,提高了查找速度。 5. **取模操作**:为了保证结果在1到1000000007之间,每次增加逆序对的数量时,都需要更新计数并取模。 以下是伪代码描述: ``` def count_inversions(arr): n = len(arr) sorted_arr = arr.copy().sort() inversions_count = 0 hash_table = {sorted_arr[i]: i for i in range(n)} for i in range(n - 1): inversions_count += (n - 1) - hash_table[arr[i]] # 当前元素之前还有 n-i-1 个元素大于它 inversions_count %= 1000000007 return inversions_count ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值