当前位置: 首页 > news >正文

位运算题目:黑板异或游戏

文章目录

  • 题目
    • 标题和出处
    • 难度
    • 题目描述
      • 要求
      • 示例
      • 数据范围
  • 解法
    • 思路和算法
    • 代码
    • 复杂度分析

题目

标题和出处

标题:黑板异或游戏

出处:810. 黑板异或游戏

难度

8 级

题目描述

要求

给定一个整数数组 nums \texttt{nums} nums,表示写在黑板上的数字。

Alice 和 Bob 轮流从黑板上擦掉一个数字,Alice 先手。如果擦掉一个数字后,剩余的所有数字按位异或运算的结果等于 0 \texttt{0} 0 的话,当前玩家游戏失败。如果只剩一个数字,按位异或运算的结果是它本身;如果无数字剩余,按位异或运算的结果是 0 \texttt{0} 0

并且,轮到某个玩家时,如果当前黑板上所有数字按位异或运算结果等于 0 \texttt{0} 0,这个玩家获胜。

假设两个玩家使用最优策略,当且仅当 Alice 获胜时返回 true \texttt{true} true

示例

示例 1:

输入: nums = [1,1,2] \texttt{nums = [1,1,2]} nums = [1,1,2]
输出: false \texttt{false} false
解释:
Alice 有两个选择:擦掉 1 \texttt{1} 1 2 \texttt{2} 2
如果 Alice 擦掉 1 \texttt{1} 1,数组变成 [1, 2] \texttt{[1, 2]} [1, 2]。剩余数字按位异或得到 1 ⊕ 2 = 3 \texttt{1} \oplus \texttt{2} = \texttt{3} 12=3。那么 Bob 可以擦掉任意数字,因为 Alice 会成为擦掉最后一个数字的人,她总是会输。
如果 Alice 擦掉 2 \texttt{2} 2,那么数组变成 [1, 1] \texttt{[1, 1]} [1, 1]。剩余数字按位异或得到 1 ⊕ 1 = 0 \texttt{1} \oplus \texttt{1} = \texttt{0} 11=0。Alice 仍然会输掉游戏。

示例 2:

输入: nums = [0,1] \texttt{nums = [0,1]} nums = [0,1]
输出: true \texttt{true} true

示例 3:

输入: nums = [1,2,3] \texttt{nums = [1,2,3]} nums = [1,2,3]
输出: true \texttt{true} true

数据范围

  • 1 ≤ nums.length ≤ 1000 \texttt{1} \le \texttt{nums.length} \le \texttt{1000} 1nums.length1000
  • 0 ≤ nums[i] < 2 16 \texttt{0} \le \texttt{nums[i]} < \texttt{2}^\texttt{16} 0nums[i]<216

解法

思路和算法

如果初始时数组 nums \textit{nums} nums 中的所有数字的按位异或运算结果是 0 0 0,则 Alice 获胜。以下考虑初始时数组 nums \textit{nums} nums 中的所有数字的按位异或运算结果不是 0 0 0 的情况。

如果 Alice 面临失败,则只有一种情况:Alice 擦掉数字之前,剩余的所有数字的按位异或运算结果不是 0 0 0,且 Alice 擦掉任意一个数字之后,剩余的所有数字的按位异或运算结果是 0 0 0

n n n 表示数组 nums \textit{nums} nums 的长度,用 X X X 表示数组 nums \textit{nums} nums 中的所有数字的按位异或运算结果:

X = nums [ 0 ] ⊕ nums [ 1 ] ⊕ … ⊕ nums [ n − 1 ] ≠ 0 X = \textit{nums}[0] \oplus \textit{nums}[1] \oplus \ldots \oplus \textit{nums}[n - 1] \ne 0 X=nums[0]nums[1]nums[n1]=0

对于 0 ≤ i < n 0 \le i < n 0i<n,用 X i X_i Xi 表示擦掉 nums [ i ] \textit{nums}[i] nums[i] 之后剩余的所有数字的按位异或运算结果,则对于每个 0 ≤ i < n 0 \le i < n 0i<n 都有 X i = 0 X_i = 0 Xi=0。用 Y Y Y 表示所有 X i X_i Xi 的按位异或运算结果:

Y = X 0 ⊕ X 1 ⊕ … ⊕ X n − 1 = 0 Y = X_0 \oplus X_1 \oplus \ldots \oplus X_{n - 1} = 0 Y=X0X1Xn1=0

对于每个 0 ≤ i < n 0 \le i < n 0i<n 都有 X = X i ⊕ nums [ i ] X = X_i \oplus \textit{nums}[i] X=Xinums[i],等价于 X i = X ⊕ nums [ i ] X_i = X \oplus \textit{nums}[i] Xi=Xnums[i],代入 Y Y Y 的表达式,用 X ( n ) X^{(n)} X(n) 表示 n n n X X X 的按位异或运算结果:

Y = X ( n ) ⊕ ( nums [ 0 ] ⊕ nums [ 1 ] ⊕ … ⊕ nums [ n − 1 ] ) = X ( n ) ⊕ X = X ( n + 1 ) Y = X^{(n)} \oplus (\textit{nums}[0] \oplus \textit{nums}[1] \oplus \ldots \oplus \textit{nums}[n - 1]) = X^{(n)} \oplus X = X^{(n + 1)} Y=X(n)(nums[0]nums[1]nums[n1])=X(n)X=X(n+1)

由于 Y = 0 Y = 0 Y=0,因此 X ( n + 1 ) = 0 X^{(n + 1)} = 0 X(n+1)=0,即 n + 1 n + 1 n+1 X X X 的按位异或运算结果是 0 0 0。由于 X ≠ 0 X \ne 0 X=0,因此只有当 n + 1 n + 1 n+1 是偶数即 n n n 是奇数时,上式才可能成立。当 n n n 是偶数时,Alice 一定可以找到一个数字,擦掉该数字之后,剩余的所有数字的按位异或运算的结果不是 0 0 0,因此 Alice 可以获胜。

根据上述分析,只要满足以下两个条件之一,Alice 就能获胜:

  • 初始时数组 nums \textit{nums} nums 中的所有数字的按位异或运算结果是 0 0 0

  • 初始时数组 nums \textit{nums} nums 的长度是偶数。

实现方面,可以首先判断数组 nums \textit{nums} nums 的长度的奇偶性,如果数组长度是偶数则直接返回 true \text{true} true,只有当数组长度是奇数时才需要遍历数组计算按位异或运算结果是否为 0 0 0,该做法对于数组长度是偶数的情形的时间复杂度是 O ( 1 ) O(1) O(1)

代码

class Solution {public boolean xorGame(int[] nums) {if (nums.length % 2 == 0) {return true;}int xor = 0;for (int num : nums) {xor ^= num;}return xor == 0;}
}

复杂度分析

  • 时间复杂度: O ( n ) O(n) O(n),其中 n n n 是数组 nums \textit{nums} nums 的长度。当 n n n 是偶数时直接返回 true \text{true} true,时间复杂度是 O ( 1 ) O(1) O(1),当 n n n 是奇数时需要遍历数组计算所有数字的按位异或运算结果,时间复杂度是 O ( n ) O(n) O(n),因此最差情况的时间复杂度是 O ( n ) O(n) O(n)

  • 空间复杂度: O ( 1 ) O(1) O(1)

http://www.xdnf.cn/news/414991.html

相关文章:

  • 火山云网站搭建
  • AES-128 加密与解密详解
  • 分享AI时代数据智能人才定向就业班(暑期班)
  • 【Linux 系统调试】syslog:Linux 系统日志工具详解
  • DAY22kaggle泰坦尼克号
  • 手写 vue 源码 === watch 实现
  • 学习黑客5分钟深入浅出理解系列之Windows compmgmt
  • 配置Hadoop集群-免密登录
  • dfs第二次加训 详细题解 下
  • STM32G474VET6-CAN FD使用经典模式+过滤报文ID
  • ESOP系统如何帮助玩具工厂实现生产数据实时展示
  • rufus+Ubuntu 18.04 镜像
  • Promise/A+ 规范中文解读
  • Matlab基于PSO-MVMD粒子群算法优化多元变分模态分解
  • 【C语言指针超详解(五)】--回调函数,qsort函数的理解和使用,qsort函数的模拟实现
  • 类神经网络训练失败怎么办?
  • 中央处理器(CPU)(概述、指令周期)
  • 阿里云服务器核心用途解析:从基础应用到行业创新​
  • c++刷题便捷函数(类似于stoi的小函数)
  • 超越合并速度(merge speed):AI如何重塑开发者协作
  • Hadoop集群的常用命令
  • axi uart 16550 ip core使用流程
  • 一、HAL库的设计理念详解:从架构到实践
  • 274、H指数
  • StringBuilder,StringJoiner,StringBuffer字符串处理类深度解析
  • 从零到精通:GoFrame 的 garray 模块深度解析与实战经验分享
  • Nacos源码—8.Nacos升级gRPC分析五
  • 【K8S学习之生命周期钩子】详细了解 postStart 和 preStop 生命周期钩子
  • 【日撸 Java 三百行】Day 13(链表)
  • 【AIGC梦幻婚纱美学】:白纱与花卉的浪漫算法融合