package LeetCode_775 /** * 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: 1. A will be a permutation of [0, 1, ..., A.length - 1]. 2. A will have length in range [1, 5000]. 3. The time limit for this problem has been reduced. * */ class Solution { /* * solution 1: bruce force, Time:O(n^2), Space:O(1); * solution 2: Merge Sort to calculate global count, Time:O(nlogn), Space:O(n); * */ fun isIdealPermutation(A: IntArray): Boolean { var localCount = 0 var globalCount = 0 //local: i with 0 <= i < N and A[i] > A[i+1]. for (i in 0 until A.size - 1) { if (A[i] > A[i + 1]) { localCount++ } } //global: number of i < j with 0 <= i < j < N and A[i] > A[j]. for (i in A.indices) { for (j in i + 1 until A.size) { if (A[i] > A[j]) { if (globalCount++ > localCount) { return false } } } } return localCount == globalCount } }
Solution 2:
fun isIdealPermutation(A: IntArray): Boolean { var localCount = 0 var globalCount = 0 //local: i with 0 <= i < N and A[i] > A[i+1]. for (i in 0 until A.size - 1) { if (A[i] > A[i + 1]) { localCount++ } } //global: number of i < j with 0 <= i < j < N and A[i] > A[j]. val n = A.size globalCount = mergeSort(A, 0, n - 1, IntArray(n)) return localCount == globalCount } private fun mergeSort(nums: IntArray, l: Int, r: Int, temp: IntArray): Int { if (l >= r) { return 0 } val mid = l + (r - l) / 2 var count = mergeSort(nums, l, mid, temp) + mergeSort(nums, mid + 1, r, temp) var i = l var j = mid + 1 var index = 0 while (i <= mid && j <= r) { if (nums[i] <= nums[j]) { temp[index++] = nums[i++] } else { count += mid - i + 1 temp[index++] = nums[j++] } } //checking remaining while (i <= mid) { temp[index++] = nums[i++] } while (j <= r) { temp[index++] = nums[j++] } //copy temp to original array index = 0 for (i in l until r + 1) { nums[i] = temp[index++] } return count }