题目一 数组中只出现一次的数字

题目

一个整型数组里除了两个数字之外,其他的数字都出现了两次。请写程序找出这两个只出现一次的数字

题解

  • 异或。
  • 先考虑:数组中只有一个数字只出现了一次,其他数字都出现了两次,怎么找出这个数字?全部异或,结果即为所求数字。
  • 那么,原问题可以将原数组分成两个集合,两个集合都满足上面的题目,则可求出两个出现一次的数字,那么分组方法?分组:将所有数都做异或,一定至少有一位是1,因为存在两个不相同数字。先找出这一位,然后按这一位是0/1分为两组,两组自然就满足了上面的要求,可求的结果。
  • 综上,步骤一:分组,步骤二:全部异或求得数字。

相关

  • 异或运算可初始化为0,因为0与任何数异或都是它本身。
  • 找到最后一个1:num&(~num+1)

代码

public class Main {
public static void main(String[] args) {
int[] arr= {2,4,3,6,3,2,5,5};
int[] num1=new int[1];
int[] num2=new int[1];
FindNumsAppearOnce(arr,num1,num2);
System.out.println(num1[0]);
System.out.println(num2[0]);
} //num1,num2分别为长度为1的数组。传出参数
//将num1[0],num2[0]设置为返回结果
public static void FindNumsAppearOnce(int [] array,int num1[] , int num2[]) {
if(array==null||array.length<2) {
return;
} //所有数异或
int xorResult=0;
for(int i=0;i<array.length;++i) {
xorResult^=array[i];
} //找到(最后一个)为1的位
int bitPos=findFirstOnePos(xorResult); num1[0]=0;
num2[0]=0;
for(int i=0;i<array.length;++i) {
if((array[i]&bitPos)==0) {//bitPos位为0的分为一组
num1[0]^=array[i];//该组内所有数异或,结果即为第一个出现一次的数
}
else {//bitPos为1的分为一组
num2[0]^=array[i];//该组内所有数异或,结果即为第二个出现一次的数
}
}
} //获得二进制最后一个1的位置
private static int findFirstOnePos(int num) {
return num&(~num+1);
}
}

题目二 数组中唯一只出现一次的数字

题目

一个数组中,一个数字只出现一次,其他数字都出现三次,找出只出现一次的数字

题解

  • 用一个32位数组,记录每个数对应位相加的和,每位%3的结果得到的数字就是所求数字。

    时间复杂度O(n),空间复杂度O(1).

  • 其他解法:排序,再找,时间复杂度O(nlogn);或者哈希表,空间复杂度O(n).

相关

涉及到了知道哪些位是1,通过位移和与运算得到最终的数。

代码

public class Main {
public static void main(String[] args) {
int[] arr= {1,2,3,3,2,1,4,1,2,3};
System.out.println(occurOnce(arr));
} public static int occurOnce(int[] nums) {
int[] bitSum=new int[32];
for(int i=0;i<nums.length;++i) {
int bitMask=1;
for(int j=0;j<31;++j) {
if((nums[i]&bitMask)!=0) {
++bitSum[j];
}
bitMask<<=1;
}
} int ans=0;
for(int i=31;i>=0;--i) {//高位移的多,按从高到低位遍历
ans<<=1;
ans+=bitSum[i]%3;
}
return ans;
}
}

[剑指Offer]56-数组中数字出现的次数(位运算)的更多相关文章

  1. 【位运算】剑指offer 56. 数组中数字出现的次数

    这是一系列位运算的题目,本文将由浅入深,先从最简单的问题开始: 问题1: 一个数组中只有一个数字出现过1次,其余数字都出现过两次,请找到那个只出现1次的数字.要求时间复杂度是 \(O(n)\),空间复 ...

  2. 剑指offer——62数组种数字出现的次数

    题目描述 一个整型数组里除了两个数字之外,其他的数字都出现了两次.请写程序找出这两个只出现一次的数字. 题解: 我们想到异或运算的一个性质:任何一个数字异或它自己都等于0.也就是说,如果我们从头到尾依 ...

  3. 剑指Offer:数组中出现次数超过一半的数字【39】

    剑指Offer:数组中出现次数超过一半的数字[39] 题目描述 数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字.例如,输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}.由于这 ...

  4. 《剑指offer》数组中只出现一次的数字

    本题来自<剑指offer> 数组中只出现一次的数字 题目: 一个整型数组里除了两个数字之外,其他的数字都出现了两次.请写程序找出这两个只出现一次的数字. 思路: 思路一:在<剑指of ...

  5. 剑指 Offer 39. 数组中出现次数超过一半的数字 + 摩尔投票法

    剑指 Offer 39. 数组中出现次数超过一半的数字 Offer_39 题目描述 方法一:使用map存储数字出现的次数 public class Offer_39 { public int majo ...

  6. 剑指 Offer 03. 数组中重复的数字

    剑指 Offer 03. 数组中重复的数字 找出数组中重复的数字. 在一个长度为 n 的数组 nums 里的所有数字都在 0-n-1 的范围内.数组中某些数字是重复的,但不知道有几个数字重复了,也不知 ...

  7. 菜鸟刷题路:剑指 Offer 03. 数组中重复的数字

    剑指 Offer 03. 数组中重复的数字 哈希表/set class Solution { public int findRepeatNumber(int[] nums) { HashSet< ...

  8. 剑指 Offer 39. 数组中出现次数超过一半的数字

    剑指 Offer 39. 数组中出现次数超过一半的数字 数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字. 你可以假设数组是非空的,并且给定的数组总是存在多数元素. 示例 1: 输入: [ ...

  9. 5.1 剑指 Offer 03. 数组中重复的数字

    类型题:剑指 Offer 03. 数组中重复的数字 找出数组中重复的数字.在一个长度为 n 的数组 nums 里的所有数字都在 0-n-1 的范围内.数组中某些数字是重复的,但不知道有几个数字重复了, ...

随机推荐

  1. MMD日文乱码解决

    记录一下自己在学习MMD遇到的问题. 日文乱码是很常见的,因为很多MMD资源是日本的. 1.解压乱码 我以好压为例,其他解压软件也是可以通过设置解决的 设置

  2. c cpp编程用到的系统边角与其拾遗

    拾遗 Q:unix编程怎么查一个函数在哪个头文件中 A: 可以用诸如 man 3 printf Q: man后面接个数字什么意思,如man 3 printf A:如下 man man中的引用 下表显示 ...

  3. 简单的main方法调用一个加减法函数背后的细节

    测试程序 /* * AddTest.c * * Created on: 2019年10月13日 * Author: appweb */ #include <stdio.h> int add ...

  4. python库安装失败的解决方法

    安装python库 在https://www.lfd.uci.edu/~gohlke/pythonlibs 中,搜索对应库名称 选取对应版本下载 在cmd窗口中,用命令 pip install+文件路 ...

  5. Mybatis 和 Solon 在一起的升级版

    终于说通 Solon 作者,让他为 Solon 框架添加事务注解支持了:并且把 mybatis-solon-plugin 的 @Df 注解更名为 @Db ,接地气多了(Df是什么鬼呢?新手肯定这么想. ...

  6. Kafka Producer源码解析一:整体架构

    一.Producer整体架构 Kafka Producer端的架构整体也是一个生产者-消费者模式 Producer线程调用send时,只是将数据序列化后放入对应TopicPartition的Deque ...

  7. ASP.NET Core3.1使用IdentityServer4中间件系列随笔(二):创建API项目,配置IdentityServer保护API资源

    配套源码:https://gitee.com/jardeng/IdentitySolution 接上一篇<ASP.NET Core3.1使用IdentityServer4中间件系列随笔(一):搭 ...

  8. JAVA虚拟机故障诊断总结

    一.JAVA运行时数据区               1.堆(-Xmx与-Xms):所有线程共享.  目的:用来存放对象实例.所有对象实例和数组都要在堆上分配内存.JAVA堆是垃圾收集器管理的主要区域 ...

  9. 赫然:Windows Live Writer 批量博客更新软件使用教程

    http://www.wocaoseo.com/thread-144-1-1.html 推广人员需要使用多个博客,一个一个登陆更新是很麻烦的事情,网上的桌面批量更新博客软件也不少,今天在此推荐大家使用 ...

  10. Appium + Python App自动化第一个脚本

    今天跟大家讲解一个Appium和Python App自动化的脚本.[1]打开你的夜神模拟器(或者连接你的手机) [2]打开桌面的Appium [3]下载你要测的App的apk文件,放到桌面[4]拖动你 ...