leetcode-找出数组中出现1次的数字
例题1 https://leetcode-cn.com/problems/single-number/
给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现两次。找出那个只出现了一次的元素。
解析:
由于公式 a ^ a = 0.又 b & 0 = b因此我们直接遍历数组之后全部异或就行
class Solution {
public int singleNumber(int[] nums) {
int result = 0;
for(int item:nums) {
result ^= item;
}
return result;
}
}
例题2 https://www.nowcoder.com/practice/e02fdb54d7524710a7d664d082bb7811?tpId=13&tqId=11193&tPage=2&rp=2&ru=%2Fta%2Fcoding-interviews&qru=%2Fta%2Fcoding-interviews%2Fquestion-ranking
一个整型数组里除了两个数字之外,其他的数字都出现了两次。请写程序找出这两个只出现一次的数字a,b。
解析:
我们当然得参考上一个题目,我们应当要想如何把这个题转换成第一种题型,我们可以这么考虑,把这个数组分为2部分,不同的两个数分别分在不同的组,那么再使用第一种方法对他进行异或肯定就能一下得出结果了。那么,关键在于,如何才能分组呢。我们可以先抑或数组得到结果temp,然后找到temp的二进制形式的第一个为1的位,为1代表着数字a,b在这个位置上的值是不同的,然后我们就可以根据这个原理进行分组了!
import java.util.ArrayList;
import java.util.List;
public class Solution {
public void FindNumsAppearOnce(int [] array,int num1[] , int num2[]) {
if(array == null || array.length == 0) {
return;
}
else {
int temp = 0;
for(int i = 0; i < array.length; i++) {
temp ^= array[i];
}
int val = 1 << findIndex(temp);
List<Integer> list1 = new ArrayList<>();
List<Integer> list2 = new ArrayList<>();
for (int i = 0; i < array.length; i++) {
if((val & array[i]) != 0) {
list1.add(array[i]);
}else {
list2.add(array[i]);
}
}
for (Integer integer : list1) {
num1[0] ^= integer;
}
for (Integer integer : list2) {
num2[0] ^= integer;
}
}
}
//// 查找第一位不为0的位
public int findIndex(int bitInt) {
int index = 0;
while (index < 32 && ((1 << index) & bitInt) == 0) {
index++;
};
return index;
}
}
例题3 https://leetcode-cn.com/problems/single-number-ii/
给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现了三次。找出那个只出现了一次的元素a。
解析 这类题的通用解法其实有2中,第一种为额外存储空间hashmap,第二种为以下。还是利用位运算,
利用整形二进制只有32位。因此我们可以找出每一个二进制位是否在a中存在,如果存在则保留这个二进制位。
class Solution {
public int singleNumber(int[] nums) {
int ret = 0;
for (int i = 0; i < 32; i++) {
int mask = 1 << i;
int cnt = 0;
for (int j = 0; j < nums.length; j++) {
if ((nums[j] & mask) != 0) {
cnt++;
}
}
if (cnt % 3 != 0) {
ret |= mask;
}
}
return ret;
}
}