您的位置:首页 > 新闻 > 资讯 > 个人网页设计首页_深圳人为什么不想去龙岗_推广营销策划方案_烟台seo关键词排名

个人网页设计首页_深圳人为什么不想去龙岗_推广营销策划方案_烟台seo关键词排名

2024/12/26 9:44:05 来源:https://blog.csdn.net/I_am_toutu/article/details/142782620  浏览:    关键词:个人网页设计首页_深圳人为什么不想去龙岗_推广营销策划方案_烟台seo关键词排名
个人网页设计首页_深圳人为什么不想去龙岗_推广营销策划方案_烟台seo关键词排名

2401. 最长优雅子数组
题目含义:找出数组中最长优雅子数组,这个优雅子数组表示对任意两个元素进行按位与 AND 运算的结果均为 0,且最短的优雅子数组的长度为 1。

这就意味着子数组的元素在二进制,从底到高位的第 i 位上,至多有一个元素的第 i 位比特是 1,其余元素在相同位上是比特 0,相当于这些元素同一位上不存在同时为 1 的情况;例如子数组中不可能有两个奇数(最低位为 1),因为这两个奇数的 AND 结果大于 0。

我们可以利用滑动窗口来求解优雅子数组,只要保证窗口内的元素在同一位上不存在同时为 1 即可,我们使用异或运算来统计窗口内的每一个位上 1 的个数;其中异或操作的原理是一个位上如果不同则为1,相同则为0,比如 1010 ⊕ 1001 = 0011 1010 \oplus 1001 = 0011 10101001=0011

假设有数组 n u m s nums nums,此时窗口的范围为 [left, right-1],对这个范围内的元素进行异或操作得到 m a s k mask mask,此时新加入一个元素 nums[right]:
如果 ( m a s k & n u m s [ r i g h t ] ) = 0 (mask \ \& \ nums[right]) = 0 (mask & nums[right])=0,则表明子数组中所有数的 AND 的结果是 0,则计算当前窗口大小;如果 ( m a s k & n u m s [ r i g h t ] ) ! = 0 (mask \ \& \ nums[right]) \ != 0 (mask & nums[right]) !=0,则表明 n u m s [ r i g h t ] nums[right] nums[right] 与窗口内的元素在至少一个位上同时出现 1 的情况,此时将 l e f t + + left++ left++,缩小窗口的范围;直到出现第一种情况,停止窗口的缩小。

流程:
① 定义变量 ans、left 和 mask,分别表示最长优美子数组的长度、滑动窗口的左边界、以及记录当前窗口中所有数的按位或的结果;
② 遍历数组,使用 right 作为滑动窗口的右边界:
(1) 判断新加入的 nums[right] 和当前窗口中的某个数字有冲突(即 AND 不为 0):如果有冲突,则用异或移除 nums[left] 更新 mask 的结果( a ⊕ b ⊕ b = a a \oplus b \oplus b = a abb=a,交换律)且不断让 left 向右移动,直到窗口内的元素与 nums[right] 不再有冲突;
(2) 更新 mask,将 nums[right] 加入到 mask 中;
(3) 更新最大子数组长度 ans;
③ 返回最终找到的最大优美子数组的长度 ans。

class Solution {
public:int longestNiceSubarray(vector<int>& nums) {int ans = 0, left = 0, mask=0;for (int right=0; right < nums.size(); right++) {while ((mask & nums[right]) != 0) mask ^= nums[left++];// 如果没有进入 while,表示 nums[right] 与子数组[left, right-1] 的AND结果为0mask ^= nums[right];   ans = max(ans, right-left+1);}return ans;}
};
/*** @param {number[]} nums* @return {number}*/
var longestNiceSubarray = function(nums) {let ans = 0, left = 0, mask=0;for (let right=0; right < nums.length; right++) {while ((mask & nums[right]) != 0) mask ^= nums[left++];mask ^= nums[right];   // 异或运算符对同一个数字作用两次就会还原ans = Math.max(ans, right-left+1);}return ans;
};

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com