数组排序,既和前不一样又和后不一样的就是唯一的一个
public static int numberOnce(int[] nums) {
Arrays.sort(nums);
if (nums.length > 2 && nums[0] != nums[1]) {//避免只有一个元素的数组
return nums[0];
}
if (nums.length > 2 && nums[nums.length - 2] != nums[nums.length - 1]) {
return nums[nums.length - 1];
}
for (int i = 1; i < nums.length - 1; i++) {
if (nums[i] != nums[i - 1] && nums[i] != nums[i + 1]) {
return nums[i];
}
}
return nums[0];//只有一个元素的数组
}
哈希表
位运算
只有一个数出现了一次,其他数都出现了三次,那么别的数的每个二进制位加起来的和除3一定为0。
所以如果某个二进制位取余3不为0那么这个数就是所要求的答案的某个二进制位,再把它导出来加起来就得到答案。
力扣每日一题:137. 只出现一次的数字 II(C++) - 知乎 (zhihu.com)
一些符号解释
(num >> i) & 1是将num左移i位进行按位与,即为保留num的第i位,其余位置零
如果num的第i位为0,则(num >> i) & 1的值为0,否则不为0
|=
按位或赋值运算符
按位或赋值运算符使用两个操作数的二进制表示,对它们执行按位或运算并将结果分配给变量
x |= y // x = x | y
与运算:针对补码进行运算
public int singleNumber(int[] nums) {
int ans = 0;
for (int i = 0; i < 32; ++i) {
int total = 0;
for (int num: nums) {
//将每个二进制位加一起
total += ((num >> i) & 1);//保留num的第i位,其余位为0,对于每个元素的第i位进行相加
}
if (total % 3 != 0) {//是否整除3,即为是否是所求的数
ans |= (1 << i);//1 << i表示将1左移i位
//ans = ans | (1 << i) 将二进制还原为十进制数
}
}
return ans;
}
代码
import org.junit.Test;
import java.util.Arrays;
public class NumberOnce {
@Test
public void test() {
int[] nums = new int[]{2, 2, 3, 2};
System.out.println(numberOnce(nums));
int[] nums1 = new int[]{0,1,0,1,0,1,99};
System.out.println(numberOnce(nums1));
System.out.println(singleNumber(nums1));
}
public static int numberOnce(int[] nums) {
Arrays.sort(nums);
if (nums.length > 2 && nums[0] != nums[1]) {//避免只有一个元素的数组
return nums[0];
}
if (nums.length > 2 && nums[nums.length - 2] != nums[nums.length - 1]) {
return nums[nums.length - 1];
}
for (int i = 1; i < nums.length - 1; i++) {
if (nums[i] != nums[i - 1] && nums[i] != nums[i + 1]) {
return nums[i];
}
}
return nums[0];//只有一个元素的数组
}
public int singleNumber(int[] nums) {
int ans = 0;
for (int i = 0; i < 32; ++i) {
int total = 0;
for (int num: nums) {
//将每个二进制位加一起
total += ((num >> i) & 1);//保留num的第i位,其余位为0,对于每个元素的第i位进行相加
}
if (total % 3 != 0) {//是否整除3,即为是否是所求的数
ans |= (1 << i);//1 << i表示将1左移i位
//ans = ans | (1 << i) 将二进制还原为十进制数
}
}
return ans;
}
}