You are given an integer array nums
of length n
which represents a permutation of all the integers in the range [0, n - 1]
.
The number of global inversions is the number of the different pairs (i, j)
where:
0 <= i < j < n
nums[i] > nums[j]
The number of local inversions is the number of indices i
where:
0 <= i < n - 1
nums[i] > nums[i + 1]
Return true
if the number of global inversions is equal to the number of local inversions.
Example 1:
Input: nums = [1,0,2] Output: true Explanation: There is 1 global inversion and 1 local inversion.
Example 2:
Input: nums = [1,2,0] Output: false Explanation: There are 2 global inversions and 1 local inversion.
Constraints:
n == nums.length
1 <= n <= 105
0 <= nums[i] < n
nums
are unique.nums
is a permutation of all the numbers in the range [0, n - 1]
.When you get asked this question in a real-life environment, it will often be ambiguous (especially at FAANG). Make sure to ask these questions in that case:
The brute force method is the simplest way to check if two types of unusual orderings are the same. We will directly count how many times each type of unusual ordering occurs and then compare those counts to each other to verify they're equal.
Here's how the algorithm would work step-by-step:
def global_and_local_inversions_brute_force(numbers):
local_inversion_count = 0
# Count local inversions (adjacent inversions).
for index in range(len(numbers) - 1):
if numbers[index] > numbers[index + 1]:
# Local inversion found. Increment the counter.
local_inversion_count += 1
global_inversion_count = 0
# Count global inversions (all inversions).
for first_index in range(len(numbers)):
for second_index in range(first_index + 1, len(numbers)):
# Comparing each number to every number after it.
if numbers[first_index] > numbers[second_index]:
# Increment global inversion count.
global_inversion_count += 1
# Determining if local and global inversions are equal.
return local_inversion_count == global_inversion_count
The key insight is that a global inversion is always a local inversion. So, to determine if the number of global inversions is equal to the number of local inversions, we only need to check if there is a global inversion that is *not* a local inversion. If we find one, we know the counts are different.
Here's how the algorithm would work step-by-step:
def global_and_local_inversions(numbers) -> bool:
list_length = len(numbers)
for i in range(list_length):
# Check each number for non-local global inversions
for j in range(i + 2, list_length):
#Found a global inversion that is not a local inversion
if numbers[i] > numbers[j]:
return False
# No non-local global inversions were found
return True
Case | How to Handle |
---|---|
Null or empty input array | Return true since an empty array trivially satisfies the condition of equal global and local inversions. |
Array with only one element | Return true since there are no inversions at all. |
Array with two elements in sorted order | Return true since there are no inversions. |
Array with two elements in reverse order | Return true since the one global inversion is also a local inversion. |
Array with many elements already sorted except for one local inversion at the end | The solution needs to correctly identify that the single local inversion at the end results in only one global inversion as well. |
Array with elements in strictly decreasing order | This worst case must be handled carefully as every adjacent pair constitutes a global inversion, so it has to be checked if all global inversions are local. |
Array with all identical elements | Return true as there are no global or local inversions. |
Integer overflow during comparisons with large values | Use long data type to handle potential integer overflow. |