problem: 3097. 或值至少为 K 的最短子数组 II
思路:首先或运算只会使得或的结果只会更大或者不变,因此最多也就只有三十一种可能或的结果。我们可以枚举每个子数组的右端点,顺带维护一下以每个右端点结尾的或值和他的坐标最大值,(就是子数组的右值是固定的了,而子数组的左值越大越好,这样子数组才尽可能的短)
Ps:如果去重部分不太了解可以先去刷一下这道题26. 删除有序数组中的重复项
Accode:
class Solution {
public:
int minimumSubarrayLength(vector<int>& nums, int k) {
int ans = 0x3f3f3f3f;
vector<pair<int,int>> ors;
int len = nums.size();
for(int i=0;i<len;i++){
//ors.push_back({nums[i],i});
vector<pair<int,int>> tmp;
for(int j=0;j<ors.size();j++){
tmp.push_back({nums[i]|ors[j].first,ors[j].second});
}
int l=0;
tmp.push_back({nums[i],i});
//去重操作
for(int r=0;r<tmp.size();r++){
if(tmp[l].first==tmp[r].first){
tmp[l].second = tmp[r].second;
}
else{
tmp[++l] = tmp[r];
}
if(tmp[l].first>=k) ans = min(ans,i+1-tmp[l].second);
}
ors = tmp;
ors.resize(l+1);
}
return ans == 0x3f3f3f3f?-1:ans;
}
};
时间复杂度:应该是$n*logU$左右吧,U为num[i]最大值