classSolution: deflongestNiceSubarray(self, nums: List[int]) -> int: ans = 0 for i, or_ inenumerate(nums): # 枚举子数组右端点 i j = i - 1 while j >= 0and (or_ & nums[j]) == 0: # nums[j] 与子数组中的任意元素 AND 均为 0 or_ |= nums[j] # 加到子数组中 j -= 1# 向左扩展 ans = max(ans, i - j) return ans
[sol1-Java]
1 2 3 4 5 6 7 8 9 10 11 12
classSolution { publicintlongestNiceSubarray(int[] nums) { intans=0; for (inti=0; i < nums.length; i++) { // 枚举子数组右端点 i intor=0, j = i; while (j >= 0 && (or & nums[j]) == 0) // nums[j] 与子数组中的任意元素 AND 均为 0 or |= nums[j--]; // 加到子数组中 ans = Math.max(ans, i - j); } return ans; } }
[sol1-C++]
1 2 3 4 5 6 7 8 9 10 11 12 13
classSolution { public: intlongestNiceSubarray(vector<int> &nums){ int ans = 0; for (int i = 0; i < nums.size(); i++) { // 枚举子数组右端点 i int or_ = 0, j = i; while (j >= 0 && (or_ & nums[j]) == 0) // nums[j] 与子数组中的任意元素 AND 均为 0 or_ |= nums[j--]; // 加到子数组中 ans = max(ans, i - j); } return ans; } };
[sol1-Go]
1 2 3 4 5 6 7 8 9 10 11 12
funclongestNiceSubarray(nums []int) (ans int) { for i, or := range nums { // 枚举子数组右端点 i j := i - 1 for ; j >= 0 && or&nums[j] == 0; j-- { // nums[j] 与子数组中的任意元素 AND 均为 0 or |= nums[j] // 加到子数组中 } ans = max(ans, i-j) } return }
funcmax(a, b int)int { if b > a { return b }; return a }
复杂度分析
时间复杂度:\mathcal{O}(n\log U),其中 n 为 nums 的长度,U=\max(\textit{nums})。
进一步地,既然这些数对应的集合的交集为空,我们可以用滑动窗口优化上述过程,右边加入 nums}[\textit{right}],左边移出 nums}[\textit{left}]。如果 or 与新加入的 nums}[\textit{right}] 有交集,则不断从 or 中去掉集合 nums}[\textit{left}],直到 or 与 nums}[\textit{right}] 交集为空。
classSolution: deflongestNiceSubarray(self, nums: List[int]) -> int: ans = left = or_ = 0 for right, x inenumerate(nums): while or_ & x: # 有交集 or_ ^= nums[left] # 从 or_ 中去掉集合 nums[left] left += 1 or_ |= x # 把集合 x 并入 or_ 中 ans = max(ans, right - left + 1) return ans
[sol2-Java]
1 2 3 4 5 6 7 8 9 10 11 12
classSolution { publicintlongestNiceSubarray(int[] nums) { intans=0; for (intleft=0, right = 0, or = 0; right < nums.length; right++) { while ((or & nums[right]) > 0) // 有交集 or ^= nums[left++]; // 从 or 中去掉集合 nums[left] or |= nums[right]; // 把集合 nums[right] 并入 or 中 ans = Math.max(ans, right - left + 1); } return ans; } }
[sol2-C++]
1 2 3 4 5 6 7 8 9 10 11 12 13
classSolution { public: intlongestNiceSubarray(vector<int> &nums){ int ans = 0; for (int left = 0, right = 0, or_ = 0; right < nums.size(); right++) { while (or_ & nums[right]) // 有交集 or_ ^= nums[left++]; // 从 or 中去掉集合 nums[left] or_ |= nums[right]; // 把集合 nums[right] 并入 or 中 ans = max(ans, right - left + 1); } return ans; } };
[sol2-Go]
1 2 3 4 5 6 7 8 9 10 11 12 13 14
funclongestNiceSubarray(nums []int) (ans int) { left, or := 0, 0 for right, x := range nums { for or&x > 0 { // 有交集 or ^= nums[left] // 从 or 中去掉集合 nums[left] left += 1 } or |= x // 把集合 x 并入 or 中 ans = max(ans, right-left+1) } return }
funcmax(a, b int)int { if b > a { return b }; return a }