【分析】由于或运算每位都是独立的,我们i从后向前遍历,记录每一位1出现的最靠前的下标i,具体地,初始30位的数组arr用来记录某一位最靠前的出现下标。从后向前遍历数组nums,对于每一个数num,再从0到30遍历他的每一位,如果这一位为1,那么更新arr(因为是从后向前遍历,所以这个出现的下标肯定小于之前的),如果这一位为0,查表中是否存在一个为1的下标,并把下标取最大值。
class Solution {
// 位运算
// 12:04 22
public int[] smallestSubarrays(int[] nums) {
int n = nums.length;
int[] arr = new int[30], ans = new int[n];
Arrays.fill(arr, n);
for (var i = n - 1; i >= 0; i--) {
int idx = i;
for (var j = 0; j < 30; j++) {
if ((nums[i] >> j & 1) == 1) arr[j] = i;
else if (arr[j] != n) idx = Math.max(idx, arr[j]);
}
ans[i] = idx - i + 1;
}
return ans;
}
}
class Solution {
public:
vector<int> smallestSubarrays(vector<int>& nums) {
int n = nums.size();
int arr[30] = {n};
vector<int> ans = vector<int>(n);
for (int i = n - 1; i >= 0; i--) {
int idx = i;
for (int j = 0; j < 30; j++) {
if (nums[i] >> j & 1 == 1) {
arr[j] = i;
} else if (arr[j] != n) {
idx = max(idx, arr[j]);
}
}
ans[i] = idx - i + 1;
}
return ans;
}
};