**LeetCode137. Single Number II_M
来源:互联网 发布:java log4j使用实例 编辑:程序博客网 时间:2024/05/20 20:55
137.Single Number II_M
Given an array of integers, every element appears three times except for one, which appears exactly once. Find that single one.
Note:
Your algorithm should have a linear runtime complexity. Could you implement it without using extra memory?
方法一:用两个 HashSet
当第一个 set 里面没有这个数时,添加进去;
当第一个 set 里面有这个数,第二个 set 里面没有这个数时,添加进第二个 set;
当两个 set 里面都有这个数时,删除两个 set 里面的这个数;
最后第一个 set 里面剩下的唯一的数就是我们要找的只出现一次的那个数;
注意:最后int result = singleNum.iterator().next();因为 Set 继承了Collection 接口,Collection 实现了Iterator 接口,所以可以使用 HashSet 的迭代器返回最后一个数。
public int singleNumber(int[] nums) { Set<Integer> singleNum = new HashSet<>(); Set<Integer> singleNum1 = new HashSet<>(); for(int i = 0; i < nums.length; i++){ if(singleNum.contains(nums[i])){ if(singleNum1.contains(nums[i])){ singleNum.remove(nums[i]); singleNum1.remove(nums[i]); } else{ singleNum1.add(nums[i]); } } else{ singleNum.add(nums[i]); } } int result = singleNum.iterator().next(); return result; }
方法二:用 Map
Map 中的 key 为数组中的值,value 为数组中的数出现的次数。
注意:Map 没有实现 Iterator 接口,所以 Map 没有迭代器方法,最后 int result = singleNum.keySet().iterator().next(); 最后将 Map 的 key 转换成 keyset 再使用迭代器返回最后一个数。
public int singleNumber4(int[] nums) { Map<Integer, Integer> singleNum = new HashMap<>(); for(int i = 0; i < nums.length; i++){ if(singleNum.containsKey(nums[i])){ if(singleNum.get(nums[i]).intValue() == 1){ singleNum.remove(nums[i]); singleNum.put(nums[i], 2); } else if(singleNum.get(nums[i]).intValue() == 2){ singleNum.remove(nums[i]); } }else{ singleNum.put(nums[i], 1); } } int result = singleNum.keySet().iterator().next(); return result;}
方法三:位运算 – 能返回出现 1 次和出现 2 次的数
总结: 一个数组中有一个元素只出现 1 次,其余元素出现 k 次
当 k 为偶数时,用异或的方法;
当 k 为奇数时,用位运算,数组中的每个元素的每一位相加再模 k ,结果就是只出现一次的元素。对于本题,模 3 有 3 种状态,余数为0,1,2, 所以用两位来表示00,01,10。
定义一种位相加运算规则:
00 + 1 = 01; 01 + 1 = 10; 10 + 1 = 00;
用 ab 表示当前位的状态,c 表示输入数字的当前位,next ab 表示输出位,则自己定义的运算的真值表如下图:
则 a = ( ~ a & b & c) | (a &~ b &~ c);
b=( ~ a & ~ b & c) | (~ a & b & ~ c);
a 位为 1 时,代表数只出现了两次;
b 位为 1 时,代表数只出现了一次;
所以返回 a 代表返回出现了两次的数;返回 b 代表返回出现了一次的数;返回 a|b 代表返回出现了一次或者两次的数。
public int singleNumber3(int[] nums) {//we need to implement a tree-time counter(base 3) that if a bit appears three time ,it will be zero. //#curent income ouput //# ab c/c ab/ab //# 00 1/0 01/00 //# 01 1/0 10/01 //# 10 1/0 00/10 // a=~abc+a~b~c; // b=~a~bc+~ab~c; int a=0; int b=0; for(int c:nums){ int ta=(~a&b&c)|(a&~b&~c); b=(~a&~b&c)|(~a&b&~c); a=ta; } //we need find the number that is 01,10 => 1, 00 => 0. return a|b;}
方法三:位运算
方法思路和上面一样,在真值表中找运算规则得到的运算公式不一样而已。
这里 one 为 1 代表出现一次;
two 为 1 代表出现两次;
public int singleNumber2(int[] nums) { int ones = 0, twos = 0; for(int i = 0; i < nums.length; i++){ ones = (ones ^ nums[i]) & ~twos; twos = (twos ^ nums[i]) & ~ones; } return ones;}
- **LeetCode137. Single Number II_M
- leetcode137 Single Number II
- LeetCode137 Single Number II
- leetcode137. Single Number II
- leetcode137~Single Number II
- LeetCode137. Single Number II
- LeetCode137—Single Number II
- leetcode137 Single Number II java
- LeetCode137——Single Number II
- Single Number
- single number
- Single Number
- Single Number
- Single Number
- Single Number
- Single Number
- Single Number
- Single Number
- mysql常用语句
- 守护线程------------------------Thread.setDaemon详解
- 学习Javascript闭包(Closure)
- 属性动画代码及布局
- AprilTag视觉定位系统
- **LeetCode137. Single Number II_M
- 关于windows右键反应速度变慢的问题
- 设置归档路径ora-02097 ora-16032 ora-09291 OS-ERROR(OS 123)
- 301. Remove Invalid Parentheses
- hdu5547(深搜)
- Magic Powder
- Mac env
- MY SQL初入(后续随时间增加)
- C与指针 4-6章