3644.排序排列

目标

给你一个长度为 n 的整数数组 nums,其中 nums 是范围 [0..n - 1] 内所有数字的一个 排列 。

你可以在满足条件 nums[i] AND nums[j] == k 的情况下交换下标 i 和 j 的元素,其中 AND 表示按位与操作,k 是一个非负整数。

返回可以使数组按 非递减 顺序排序的最大值 k(允许进行任意次这样的交换)。如果 nums 已经是有序的,返回 0。

排列 是数组所有元素的一种重新排列。

示例 1:

输入:nums = [0,3,2,1]
输出:1
解释:
选择 k = 1。交换 nums[1] = 3 和 nums[3] = 1,因为 nums[1] AND nums[3] == 1,从而得到一个排序后的排列:[0, 1, 2, 3]。

示例 2:

输入:nums = [0,1,3,2]
输出:2
解释:
选择 k = 2。交换 nums[2] = 3 和 nums[3] = 2,因为 nums[2] AND nums[3] == 2,从而得到一个排序后的排列:[0, 1, 2, 3]。

示例 3:

输入:nums = [3,2,1,0]
输出:0
解释:
只有当 k = 0 时,才能进行排序,因为没有更大的 k 能够满足 nums[i] AND nums[j] == k 的交换条件。

说明:

  • 1 <= n == nums.length <= 10^5
  • 0 <= nums[i] <= n - 1
  • nums 是从 0 到 n - 1 的一个排列。

思路

有一个 0 ~ n - 1 的排列 nums,如果 nums[i] & nums[j] == k,则允许交换元素 nums[i] 与 nums[j]。返回使得 nums 递增所允许的最大的 k,如果排列本来就是有序的返回 0。

任何数与 0 相与都是 0,如果想交换元素 nums[i] 和 nums[j],可以将元素 0 作为中间元素来交换,一定有解。

所有不在位置上的元素都是需要交换的,k 就是这些元素相与的结果,无论怎么排列,只是相与的顺序不同,结果是一样的。

代码


/**
 * @date 2026-10-23 9:06
 */
public class SortPermutation3644 {

    public int sortPermutation(int[] nums) {
        int n = nums.length;
        int res = Integer.MAX_VALUE;
        for (int i = 0; i < n; i++) {
            if (nums[i] != i) {
                res &= nums[i];
            }
        }
        return res == Integer.MAX_VALUE ? 0 : res;
    }

}

性能

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注