题目链接:https://leetcode.com/problems/single-number-ii/description/

题目大意:给出一串数,每个数都出现三次,只有一个数只出现一次,把这个出现一次的数找出来。

法一:利用hashMap,空间换时间,但是好像也没怎么换到时间。代码如下(耗时15ms):

     public int singleNumber(int[] nums) {
Map<Integer, Integer> map = new HashMap<Integer, Integer>();
int ans = -1;
for(int i = 0; i < nums.length; i++) {
if(map.containsKey(nums[i])) {
map.put(nums[i], map.get(nums[i]) + 1);
}
else {
map.put(nums[i], 1);
}
}
for(int i = 0; i < nums.length; i++) {
if(map.get(nums[i]) == 1) {
ans = nums[i];
break;
}
}
return ans;
}

法二:先排序,再一一计算。代码如下(耗时5ms):

     public int singleNumber(int[] nums) {
Arrays.sort(nums);
int ans = nums[0];
int cnt = 1;
int length = nums.length;
for(int i = 1; i < length; i++) {
if(nums[i] != nums[i - 1]) {
if(cnt == 1) {
break;
}
ans = nums[i];
cnt = 1;
}
else {
cnt++;
}
}
return ans;
}

法三(借鉴):利用位运算,这个方法是普遍方法,136题也可以用这个方法做,但是时间复杂度其实是o(n^2),所以也不是最优的,只是用到了位运算。借鉴自:http://blog.csdn.net/feliciafay/article/details/19004479。代码如下(耗时7ms):

     public int singleNumber(int[] nums) {
int ans = 0;
int length = nums.length;
//将每一个数取二进制位按位相加,如果都是重复的则当前位的相加和一定是3的倍数,否则当前位一定存在于要找的那个数中
//比如1,1,1,2,2,2,3这六个数将其转为二进制数按位相加,然后每一位都对3取模,最后一定可以得到3
for(int i = 0; i < 32; i++) {//计算每一位
int sum = 0;//统计每一位的和
for(int j = 0; j < length; j++) {//对每个数取第i位的数值
if(((nums[j] >> i) & 1) == 1) {//取第i位的数值
sum++;//将每个数第i位的值相加求和
sum %= 3;
}
}
if(sum != 0) {//如果对3取模后非0,则说明当前位一定是要找的数的某一位
ans |= sum << i;//将其转为十进制加入结果当中
}
}
return ans;
}

法四(借鉴):这个位运算还没看懂。https://www.cnblogs.com/yangrouchuan/p/5323327.html

 链接:https://www.nowcoder.com/questionTerminal/e02fdb54d7524710a7d664d082bb7811
来源:牛客网 /**
* 数组中有两个出现一次的数字,其他数字都出现两次,找出这两个数字
* @param array
* @param num1
* @param num2
*/
public static void findNumsAppearOnce(int [] array,int num1[] , int num2[]) {
if(array == null || array.length <= 1){
num1[0] = num2[0] = 0;
return;
}
int len = array.length, index = 0, sum = 0;
for(int i = 0; i < len; i++){
sum ^= array[i];
}
for(index = 0; index < 32; index++){
if((sum & (1 << index)) != 0) break;
}
for(int i = 0; i < len; i++){
if((array[i] & (1 << index))!=0){
num2[0] ^= array[i];
}else{
num1[0] ^= array[i];
}
}
}
/**
* 数组a中只有一个数出现一次,其他数都出现了2次,找出这个数字
* @param a
* @return
*/
public static int find1From2(int[] a){
int len = a.length, res = 0;
for(int i = 0; i < len; i++){
res = res ^ a[i];
}
return res;
}

137.Single Number II---位运算---《剑指offer》40的更多相关文章

  1. [LeetCode] Single Number II 位运算

    Given an array of integers, every element appears three times except for one. Find that single one. ...

  2. leetcode Single Number II - 位运算处理数组中的数

    题目描述: 给定一个包含n个整数的数组,除了一个数出现一次外所有的整数均出现三次,找出这个只出现一次的整数. 题目来源: http://oj.leetcode.com/problems/single- ...

  3. leetcode 136. Single Number 、 137. Single Number II 、 260. Single Number III(剑指offer40 数组中只出现一次的数字)

    136. Single Number 除了一个数字,其他数字都出现了两遍. 用亦或解决,亦或的特点:1.相同的数结果为0,不同的数结果为1 2.与自己亦或为0,与0亦或为原来的数 class Solu ...

  4. 【LeetCode】137. Single Number II 解题报告(Python)

    [LeetCode]137. Single Number II 解题报告(Python) 标签: LeetCode 题目地址:https://leetcode.com/problems/single- ...

  5. LeetCode 137. Single Number II(只出现一次的数字 II)

    LeetCode 137. Single Number II(只出现一次的数字 II)

  6. 剑指 Offer 40. 最小的k个数 + 优先队列 + 堆 + 快速排序

    剑指 Offer 40. 最小的k个数 Offer_40 题目描述 解法一:排序后取前k个数 /** * 题目描述:输入整数数组 arr ,找出其中最小的 k 个数.例如,输入4.5.1.6.2.7. ...

  7. 剑指 Offer 40. 最小的k个数

    剑指 Offer 40. 最小的k个数 输入整数数组 arr ,找出其中最小的 k 个数.例如,输入4.5.1.6.2.7.3.8这8个数字,则最小的4个数字是1.2.3.4. 示例 1: 输入:ar ...

  8. Leetcode 137 Single Number II 仅出现一次的数字

    原题地址https://leetcode.com/problems/single-number-ii/ 题目描述Given an array of integers, every element ap ...

  9. 【LeetCode】137. Single Number II (3 solutions)

    Single Number II Given an array of integers, every element appears threetimes except for one. Find t ...

  10. 【Java】 剑指offer(40) 最小的k个数

    本文参考自<剑指offer>一书,代码采用Java语言. 更多:<剑指Offer>Java实现合集   题目 输入n个整数,找出其中最小的k个数.例如输入4.5.1.6.2.7 ...

随机推荐

  1. HDU5669-Road

    题意 给一个\(n\)个点的图,标号为\(1\)到\(n\),进行\(m\)次连边\((a,b,c,d,w)\): for i in range[a,b]: for j in range[c,d]: ...

  2. BZOJ4975 区间翻转

    这个范围给的很像区间dp之类的,想了半天没一点思路,滚去看了一眼status被吓傻了.然后瞎猜了一发结论就过掉了. 求出逆序对数,判断是否为奇数即可.因为翻转区间会把将这段区间的逆序对取反,而长度为4 ...

  3. Java (Socket,ServerSocket)与(SocketChannel,ServerSocketChannel)区别和联系

    Socket 和ServerSocke 是一对 他们是java.net下面实现socket通信的类SocketChannel 和ServerSocketChannel是一对 他们是java.nio下面 ...

  4. 《Linux内核设计与实现》第5章读书笔记

    第五章 系统调用 一.系统调用概述 系统调用在Linux中称为syscall,返回的值是long型变量:如果出错,C库会将错误代码写入errno全局变量(通过调用perror()函数可以把该变量翻译成 ...

  5. 电子商务(电销)平台中商品模块(Product)数据库设计明细

    以下是自己在电子商务系统设计中的数据库设计经验总结,而今发表出来一起分享,如有不当,欢迎跟帖讨论~ 商品表 (product)|-- 自动编号 (product_id)|-- 商品名称 (produc ...

  6. [IOI2013]Dreaming

    link 一道非常类似的题目(link) 试题大意 给你一棵含有$n$个节点的有边权森林,问每次连边将会用$L$的代价,问你若此图通过加边成为树时的最小直径.$n \leq 5\times 10^5$ ...

  7. git使用笔记(十三)ls-files

    By francis_hao    Mar 18,2018   git ls-fles 显示index和工作区的文件的信息. 概要 git ls-files [-z] [-t] [-v]        ...

  8. Educational Codeforces Round 24 A 水 B stl C 暴力 D stl模拟 E 二分

    A. Diplomas and Certificates time limit per test 1 second memory limit per test 256 megabytes input ...

  9. angular 使用rxjs 监听同级兄弟组件数据变化

    angular 的官网给出了父子组件之间数据交互的方法,如ViewChild.EventEmitter 但是如果要在同级组件之间进行数据同步,似乎并没有给出太多的信息. 有时候我们想,在一个组件中修改 ...

  10. ajax 中操作this,需要先在ajax的外面给this重新定义为_this!!

    //设置为默认收货地址 $(document).on('tap','.right_none',function(){ var _this = $(this); //只有这样定义,在ajax的内部才可以 ...