首页 > 其他分享 >Minimize OR of Remaining Elements Using Operations

Minimize OR of Remaining Elements Using Operations

时间:2024-02-17 17:13:13浏览次数:20  
标签:Operations operations nums Minimize equal bitwise 按位 Using 变成

Minimize OR of Remaining Elements Using Operations

You are given a 0-indexed integer array nums and an integer k.

In one operation, you can pick any index i of nums such that 0 <= i < nums.length - 1 and replace nums[i] and nums[i + 1] with a single occurrence of nums[i] & nums[i + 1], where & represents the bitwise AND operator.

Return the minimum possible value of the bitwise OR of the remaining elements of nums after applying at most k operations.

 

Example 1:

Input: nums = [3,5,3,2,7], k = 2
Output: 3
Explanation: Let's do the following operations:
1. Replace nums[0] and nums[1] with (nums[0] & nums[1]) so that nums becomes equal to [1,3,2,7].
2. Replace nums[2] and nums[3] with (nums[2] & nums[3]) so that nums becomes equal to [1,3,2].
The bitwise-or of the final array is 3.
It can be shown that 3 is the minimum possible value of the bitwise OR of the remaining elements of nums after applying at most k operations.

Example 2:

Input: nums = [7,3,15,14,2,8], k = 4
Output: 2
Explanation: Let's do the following operations:
1. Replace nums[0] and nums[1] with (nums[0] & nums[1]) so that nums becomes equal to [3,15,14,2,8]. 
2. Replace nums[0] and nums[1] with (nums[0] & nums[1]) so that nums becomes equal to [3,14,2,8].
3. Replace nums[0] and nums[1] with (nums[0] & nums[1]) so that nums becomes equal to [2,2,8].
4. Replace nums[1] and nums[2] with (nums[1] & nums[2]) so that nums becomes equal to [2,0].
The bitwise-or of the final array is 2.
It can be shown that 2 is the minimum possible value of the bitwise OR of the remaining elements of nums after applying at most k operations.

Example 3:

Input: nums = [10,7,10,3,9,14,9,4], k = 1
Output: 15
Explanation: Without applying any operations, the bitwise-or of nums is 15.
It can be shown that 15 is the minimum possible value of the bitwise OR of the remaining elements of nums after applying at most k operations.

 

Constraints:

  • 1 <= nums.length <= 105
  • 0 <= nums[i] < 230
  • 0 <= k < nums.length

 

解题思路

  与一般的位运算题一样,把每个数看成二进制表示,然后从高位往低位去贪心,看能不能在 $k$ 次操作内使得某一位都变成 $0$。因为每次只能选相邻的两个数操作,所以可以从连续子数组的角度去考虑。这里直接举个例子来给出贪心做法。

  假设现在有 $4$ 个二进制数:$101$,$010$,$011$,$110$,并且 $k=2$。先从最高位(第 $2$ 位)开始考虑,剩下的位都不管,那么就有 $1 \; 0 \; 0 \; 1$。显然可以选择第 $1$ 个和第 $2$ 个数进行按位与,第 $3$ 个和第 $4$ 个数进行按位与,$2$ 次操作可以将最高位变成 $0$。

  再往下一位考虑看能不能变成 $0$,同时还要保证操作后最高位也要变成 $0$,有 $10 \; 01 \; 01 \; 11$。第 $1$ 个和第 $2$ 个数进行按位与得到 $00$,得到 $0$ 后考虑下一个子数组,第 $3$ 个和第 $4$ 个数进行按位与得到 $01$,这时没有下一个数了,必须要和 $00$ 进行按位与才能得到 $00$。因此在将第 $1$ 位变成 $0$ 的条件下同时最高位也要变成 $0$ 至少要操作 $3$ 次。因此第 $1$ 位不能变成 $0$,答案的第 $1$ 位必然是 $1$,既然如此在考虑之后的位时,就不需要再同时将第 $1$ 位变成 $0$ 了(直接无视第 $1$ 位即可)。

  最后再考虑第 $0$ 位,我们只需保证在将第 $0$ 位变成 $0$ 时,第 $2$ 位也变成 $0$ 即可,有 $11 \; 00 \; 01 \; 10$,第 $1$ 个和第 $2$ 个数进行按位与得到 $00$,第 $3$ 个和第 $4$ 个数进行按位与得到 $00$,因此 $2$ 次操作可以将第 $0$ 位和第 $2$ 位变成 $0$。

  在进行操作时,如果某一段数字能变成 $0$,那么需要的操作次数就是这段长度减 $1$。如果不能变成 $0$(最后一段),那么需要的操作次数就是这段长度。另外可以开一个变量 $st$,如果 $st$ 的第 $i$ 位是 $1$ 表示在操作的过程中要同时将第 $i$ 位变成 $0$,否则就不用考虑。因此每次操作实际上是按位与上 $a_i \, \& \, st$。

  AC 代码如下,时间复杂度为 $O(n\log{A})$:

class Solution {
public:
    int minOrAfterOperations(vector<int>& nums, int k) {
        int ret = 0, st = 0;
        for (int i = 29; i >= 0; i--) {
            st |= 1 << i;
            int t = -1, cnt = 0;    // 一开始令t表示全1,-1的补码就是全1
            for (auto &x : nums) {
                t &= x & st;
                if (t) cnt++;
                else t = -1;
            }
            if (cnt > k) {
                ret |= 1 << i;
                st ^= 1 << i;
            }
        }
        return ret;
    }
};

 

参考资料

  位运算 试填法【力扣周赛 382】:https://www.bilibili.com/video/BV1we411J7Y8/

标签:Operations,operations,nums,Minimize,equal,bitwise,按位,Using,变成
From: https://www.cnblogs.com/onlyblues/p/18018131

相关文章