775. Global and Local Inversions

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
    }

 

posted @ 2021-01-14 11:17  johnny_zhao  阅读(98)  评论(0编辑  收藏  举报