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;
}
}