剑指offer56(Java)-数组中出现的次数Ⅰ(中等)
题目:
一个整型数组 nums 里除两个数字之外,其他数字都出现了两次。请写程序找出这两个只出现一次的数字。要求时间复杂度是O(n),空间复杂度是O(1)。
示例 1:
输入:nums = [4,1,4,6]
输出:[1,6] 或 [6,1]
示例2:
输入:nums = [1,2,10,4,1,4,3,3]
输出:[2,10] 或 [10,2]
限制:
2 <= nums.length <= 10000
来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/shu-zu-zhong-shu-zi-chu-xian-de-ci-shu-lcof
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
解题思路:
暴力求解:哈希表,但是不符合空间复杂度
先用哈希表统计出每个数字出现的次数,由于只有两个数字出现了一次,然后遍历哈希表,将出现一次的数字放入长度为2 的数组中返回即可。
1 class Solution { 2 public int[] singleNumbers(int[] nums) { 3 Map<Integer,Integer> map = new HashMap<>(); 4 int i = 0; 5 for(int num : nums){ 6 map.put(num, map.getOrDefault(num,0) + 1); 7 } 8 int[] ans = new int[2]; 9 for (Integer key: map.keySet()){ 10 if (map.get(key) == 1) { 11 ans[i] = key; 12 i++; 13 } 14 } 15 return ans; 16 } 17 }
异或:
异或公式:
① 交换律:A ^ B ^ C = A ^C ^ B
② A^ A = 0
③ A ^ 0 = A
故一个数组的元素进行异或:
比如:[2,4,2,3,3,6] 异或:2^4^2^3^3^6 = 4 ^ 6 ^(2^2)^(3^3) = 4 ^ 6 = 0100 ^ 0110 = 0010
思路:
①先将数组中的所有值进行异或,得到异或结果xor:
②设第一个为1的二进位为最后一位即0001,即设m = 1,让 m 不断左移来与xor做 与运算(相同为1)来找到第一位为1 的二进制位:
例如:
若x&0001=1,则a 的第一位为1,
若x&0010=1,则a 的第二位为1;
以此类推……
③根据num ^ m 是否等于0来差分数组。
具体过程可以看:K神老师以及评论区的解释
代码:
1 class Solution { 2 public int[] singleNumbers(int[] nums) { 3 int xor = 0; 4 //计算所有值的异或结果 5 for (int num : nums){ 6 xor ^= num; 7 } 8 int m = 1; 9 //找到第一位为1的二进制位,即当 m & xor = 1,保存m 10 while ((m & xor) == 0){ 11 //m左移1位 12 m <<= 1; 13 } 14 //利用m来将数组分组 15 //[4,1,4,6] xor = 1 ^ 6 = 0111,m = 0001 16 //num & m = 0的为一组:[4,4,6] 17 //num & m = 1的为一组:[1] 18 int x = 0, y = 0; 19 for (int num : nums){ 20 if ((num & m) == 0){ 21 x ^= num; 22 23 } 24 else{ 25 y ^= num; 26 } 27 } 28 return new int[]{x,y}; 29 } 30 }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
2022-04-06 力扣448(java)-找到数组中所有消失的数(简单)
2022-04-06 力扣697(java)-数组的度(简单)