[LeetCode] 3011. Find if Array Can Be Sorted

CNoodle發表於2024-11-07

In one operation, you can swap any two adjacent elements if they have the same number of set bits. You are allowed to do this operation any number of times (including zero).

Return true if you can sort the array, else return false.

Example 1:
Input: nums = [8,4,2,30,15]
Output: true
Explanation: Let's look at the binary representation of every element. The numbers 2, 4, and 8 have one set bit each with binary representation "10", "100", and "1000" respectively. The numbers 15 and 30 have four set bits each with binary representation "1111" and "11110".
We can sort the array using 4 operations:

  • Swap nums[0] with nums[1]. This operation is valid because 8 and 4 have one set bit each. The array becomes [4,8,2,30,15].
  • Swap nums[1] with nums[2]. This operation is valid because 8 and 2 have one set bit each. The array becomes [4,2,8,30,15].
  • Swap nums[0] with nums[1]. This operation is valid because 4 and 2 have one set bit each. The array becomes [2,4,8,30,15].
  • Swap nums[3] with nums[4]. This operation is valid because 30 and 15 have four set bits each. The array becomes [2,4,8,15,30].
    The array has become sorted, hence we return true.
    Note that there may be other sequences of operations which also sort the array.

Example 2:
Input: nums = [1,2,3,4,5]
Output: true
Explanation: The array is already sorted, hence we return true.

Example 3:
Input: nums = [3,16,8,4,2]
Output: false
Explanation: It can be shown that it is not possible to sort the input array using any number of operations.

Constraints:
1 <= nums.length <= 100
1 <= nums[i] <= 28

判斷一個陣列是否可以變為有序。

給你一個下標從 0 開始且全是 正 整數的陣列 nums 。

一次 操作 中,如果兩個 相鄰 元素在二進位制下設定位的數目 相同 ,那麼你可以將這兩個元素交換。你可以執行這個操作 任意次 (也可以 0 次)。

如果你可以使陣列變為非降序,請你返回 true ,否則返回 false 。

示例 1:
輸入:nums = [8,4,2,30,15]
輸出:true
解釋:我們先觀察每個元素的二進位制表示。 2 ,4 和 8 分別都只有一個數位為 1 ,分別為 "10" ,"100" 和 "1000" 。15 和 30 分別有 4 個數位為 1 :"1111" 和 "11110" 。
我們可以透過 4 個操作使陣列非降序:

  • 交換 nums[0] 和 nums[1] 。8 和 4 分別只有 1 個數位為 1 。陣列變為 [4,8,2,30,15] 。
  • 交換 nums[1] 和 nums[2] 。8 和 2 分別只有 1 個數位為 1 。陣列變為 [4,2,8,30,15] 。
  • 交換 nums[0] 和 nums[1] 。4 和 2 分別只有 1 個數位為 1 。陣列變為 [2,4,8,30,15] 。
  • 交換 nums[3] 和 nums[4] 。30 和 15 分別有 4 個數位為 1 ,陣列變為 [2,4,8,15,30] 。
    陣列變成有序的,所以我們返回 true 。
    注意我們還可以透過其他的操作序列使陣列變得有序。

示例 2:
輸入:nums = [1,2,3,4,5]
輸出:true
解釋:陣列已經是非降序的,所以我們返回 true 。

示例 3:
輸入:nums = [3,16,8,4,2]
輸出:false
解釋:無法透過操作使陣列變為非降序。

思路

這是一道關於二進位制的題目。注意元素在二進位制下設定位的數目相同這個定義的意思其實就是兩個數字的二進位制表示中的 1 的個數要相同。如果兩個數字的 1 的個數相同,且他們在原陣列裡是相鄰元素,才能互相交換位置。

所以我們需要遍歷 input 陣列,看一看每個數字的 Integer.bitCount(num),如果某一串連續的數字他們的 1 的個數都相同的話,這一段數字就可以互相交換以確保他們有序。所以陣列會因為 1 的個數的不同而變得分段有序。

再次遍歷排過序的陣列,如果分段排序不能導致最後的整體有序,則返回 false,否則返回 true。

複雜度

時間O(nlogn)
空間O(1)

程式碼

Java實現

class Solution {
    public boolean canSortArray(int[] nums) {
        // corner case
        if (nums == null || nums.length == 0) {
            return true;
        }

        // normal case
        int n = nums.length;
        int i = 0;
        while (i < n) {
            int start = i;
			// 二進位制表達裡 1 的個數
            int ones = Integer.bitCount(nums[i]);
            while (i < n && Integer.bitCount(nums[i]) == ones) {
                i++;
            }
			// 分段排序
            Arrays.sort(nums, start, i);
        }

        for (int j = 1; j < n; j++) {
            if (nums[j] < nums[j - 1]) {
                return false;
            }
        }
        return true;
    }
}

相關文章