“`java
//分组异或
class Solution {
public int[] sockCollocation(int[] sockets) {
int ret = 0;
for (int i = 0; i < sockets.length; i++) {
ret = (ret^sockets[i]);
}
int div = 1;
while ((ret & div) == 0) {
div <<= 1;
}
int a = 0;
int b = 0;
for (int i = 0; i < sockets.length; i++) {
if ((sockets[i] & div) != 0) {
a ^= sockets[i];
} else {
b ^= sockets[i];
}
}
return new int[]{a,b};
}
}
分成两组
vector<int> singleNumbers(vector<int>& nums) {
int x = 0,y = 0,n = 0,m = 1;
for (int num : nums)
{
n ^= num;
}
while((n & m) == 0)
m <<= 1;
for(int num : nums){
if(num & m) x ^= num;
else y ^= num;
}
return vector<int> {x,y};
}
class Solution {
public int[] singleNumbers(int[] nums) {
int a = 0;
for(int i = 0;i < nums.length;i ++){
a=a^nums[i];
}
int m = 1;
while((m & a) == 0){
m = m << 1;
}
int x = 0, y = 0;
for(int i = 0;i < nums.length; i ++){
if((nums[i] & m) ==0){
x = x ^ nums[i];
}else{
y = y ^ nums[i];
}
}
return new int[]{x ,y};
}
}
// 数组中数字出现的次数
// 时间复杂度 O(N)
// 空间复杂度 O(1)
class Solution {
public:
vector<int> singleNumbers(vector<int>& nums) {
int x = 0; // 只出现一次的数字
int y = 0; // 只出现一次的数字
int n = 0; // 存储 nums 各元素异或结果, 即为 x^y
int m = 1;
// nums 各元素异或结果, 即为 x^y
for (int num : nums) {
n = n ^ num;
}
// eg. x = 1 = 0001
// y = 6 = 1010
// n = x ^ y = 1011
// m & n = 0001, m = 0001
while ((m & n) == 0) {
m = m << 1;
}
for (int num : nums) {
if (num & m) {
x = x ^ num;
}
else {
y = y ^ num;
}
}
return vector<int>{x, y};
}
};
java
class Solution {
public int[] singleNumbers(int[] nums) {
/*
思路:1.先对所有元素进行异或 2.将异或结果与0001/0010/0100等进行与,
结果为0则与序列中1所在的位在异或中是相等的
3.找到不相等的位之后,再与数组元素相与,此时两个只出现一个的元素可以分开,再全部异或
*/
int z = 0;
for(int i = 0; i < nums.length; i ++) { //全部异或
z = z^nums[i];
}
int m = 1;
while((m & z) == 0) { //找到不相等的位
m = m << 1;
}
//将两个只出现一次的数字进行分开后分别异或
int x = 0, y = 0;
for(int i = 0; i < nums.length; i++) {
if((m & nums[i]) == 0) {
x = x ^ nums[i];
} else {
y = y ^ nums[i];
}
}
return new int[]{x, y};
}
}
class Solution {
public int[] singleNumbers(int[] nums) {
int mod = 0;
for(int num: nums) {
mod ^= num;
}
int firstOne = 1;
while ((firstOne & mod) == 0) {
firstOne <<= 1;
}
int a = 0, b = 0;
for (int num: nums) {
if ((firstOne & num) == 0) {
a ^= num;
} else {
b ^= num;
}
}
return new int[]{a, b};
}
}
public int[] singleNumbers(int[] nums) {
int res = 0;
for(int num : nums){
res ^= num;
}
int div = (res & (res-1) ^ res);
// while((div & res) == 0){
// div <<= 1;
// }
int a = 0, b = 0;
for(int num : nums){
if((num & div) != 0){
a ^= num;
}else{
b ^= num;
}
}
return new int[]{a,b};
}
class Solution {
public:
int singleNumber(vector<int>& nums) {
int ans = 0;
for(int i = 0; i < 32; ++i){
int bitnum = 0;
for(auto n : nums)
if(n >> i & 1)
bitnum += 1;
ans |= (bitnum % 3) << i;
}
return ans;
}
};
class Solution {
public int[] singleNumbers(int[] nums) {
// 相同数异或结果为0, 某数跟0异或的结果为它本身。
// 求出不同的两个数异或的结果
int z = 0;
for(int i = 0; i < nums.length; i++){
z = z ^ nums[i];
}
// 求第几个二进制位不同(取最右的)
int m = 1;
while((z & m) == 0){
m = m << 1;
}
// 分成两组:等于m和不等于m的
int x = 0, y = 0;
for (int i = 0; i < nums.length; i++){
if((nums[i] & m) == 0) {
x = x ^ nums[i];
} else {
y = y ^ nums[i];
}
}
return new int[]{x, y};
}
}
class Solution{
public:
vector<int> singleNumbers(vector<int>& nums){
int z = 0;
// 全部元素取异或
for(int i=0; i< nums.size(); i++){
z = z ^ nums[i];
}
int m=1;
// 找出区分x,y的进制位
while((m & z) == 0){
m = m << 1;
}
int x = 0, y = 0;
for(int i =0; i< nums.size(); i++){
if((nums[i] & m) == 0){
// 结果为 0 的子数组,一边用异或统计 x
x = x ^ nums[i];
}else {
// 结果为 1 的子数组,一边用异或统计 y
y = y ^ nums[i];
}
}
return vector<int>{x,y};
}
};
class Solution:
def singleNumbers(self, nums: List[int]) -> List[int]:
res = 0
for i in range(len(nums)):
res = res ^ nums[i]
m = 1
while m & res == 0:
m = m << 1
x, y = 0, 0
for i in range(len(nums)):
if nums[i] & m == 0:
x = x ^ nums[i]
else:
y = y ^ nums[i]
return [x, y]
class Solution {
public int[] singleNumbers(int[] nums) {
int z = 0;
for(int i = 0; i < nums.length; i++) {
z = z^nums[i];
}
int m = 1;
while((z & m) == 0) {
m = m << 1;
}
int x = 0, y = 0;
for(int i = 0; i < nums.length; i++) {
if((m & nums[i]) == 0) {
x = x^nums[i];
} else {
y = y^nums[i];
}
}
return new int[]{x,y};
}
}
c++实现,看过题解,是一个比较巧妙的思路
vector singleNumbers(vector& nums) {
int len = nums.size();
int sum = 0;
for(int i =0;i<len;i++)
{
sum ^=nums[i];
}
int div = 1;
while((div&sum)0)
{
div<<=1;
}
int a=0,b= 0;
for(int n:nums)
{
if(div&n)
{
a^=n;
}
else b^=n;
}
return vector{a,b};
}
共以下 26 个回答
“`java
//分组异或
class Solution {
public int[] sockCollocation(int[] sockets) {
int ret = 0;
for (int i = 0; i < sockets.length; i++) { ret = (ret^sockets[i]); } int div = 1; while ((ret & div) == 0) { div <<= 1; } int a = 0; int b = 0; for (int i = 0; i < sockets.length; i++) { if ((sockets[i] & div) != 0) { a ^= sockets[i]; } else { b ^= sockets[i]; } } return new int[]{a,b}; } }
class Solution {
public int[] singleNumbers(int[] nums) {
int t=0;
for(int i=0;i<nums.length;i++){
t = t^nums[i];
}
int a = 1;
while((a&t)0){
a= a<<1;
}
int x=0,y=0;
for(int i=0;i<nums.length;i++){
if((a&nums[i])0){
x=x^nums[i];
}else{
y= y^nums[i];
}
}
return new int[]{x,y};
}
}
加油
“`java
public int[] singleNumbers(int[] nums) {
重要的是理解一分为二的这个思路
“`C++ findSingleNumbers(vector & nums) {
vector
int xorResult = 0;
// Step 1: 获取两个只出现一次的数字的异或结果
for (int num : nums) {
xorResult ^= num;
}
}
“`
通过位运算加上分组的形式,来计算出数值
时间O(n)
空间O(1)
时间复杂度是o(n), 空间复杂度是o(1)
位运算
时间:O(n)
空间:O(1)
【思路】将整个数组异或后得到的结果即为x^y,此时再利用异或结果将数组分为两个子集(分别包含x和y),分别对两个子集进行异或即可得到x和y
【复杂度】时间复杂度O(n),空间复杂度O(1)
时间复杂度:O(n)
空间复杂度:O(1)
时间复杂度是O(n)
空间复杂度是O(1)
时间复杂度O(n) 空间复杂度O(1)
要求找到两个数字,因此需要进行分组异或。
思路:根据异或的性质,将所有数组中的数字一起异或后,最终剩下两个数组异或的结果,且两数字二进制位不同的位的异或结果必然为1。因此,从右向左,找到第一个为1的位置,将数组分为两个部分,分别异或,便可以得到这两个数字
时间复杂度:O(n) 空间复杂度:O(1)
int 一共32位,一位位检查,模三
时间复杂度 O(n) 空间复杂度 O(1)
懂了但没全懂
时间复杂度:O(n)
空间复杂度:O(1)
时间复杂度:O(n)
空间复杂度:O(1)
MY根据 X^Y 中的 1 位进行分组
时间复杂度为O(n)
由于空间复杂度是O(1),考虑位运算
先得到所有数组异或的值,双数出现的数字会抵消,剩下两个不同的数字的异或值,
确定z的第一个1的位置从右到左,,再循环数组,分辨遇见第一个1做与运算是0或者是1,可得出这两个数,其他数字因为出现两次会被抵消
c++实现,看过题解,是一个比较巧妙的思路 singleNumbers(vector & nums) {{a,b};
vector
int len = nums.size();
int sum = 0;
for(int i =0;i<len;i++)
{
sum ^=nums[i];
}
int div = 1;
while((div&sum)0)
{
div<<=1;
}
int a=0,b= 0;
for(int n:nums)
{
if(div&n)
{
a^=n;
}
else b^=n;
}
return vector
}
时间复杂度是O(n),空间复杂度是O(1)