mirror of
https://github.com/chefyuan/algorithm-base.git
synced 2024-12-29 05:46:17 +00:00
添加py,js和cpp,解决java溢出
This commit is contained in:
parent
e761b70650
commit
9103e4379f
@ -13,7 +13,7 @@
|
||||
> 输入: [1,2,1,3,2,5]
|
||||
> 输出: [3,5]
|
||||
|
||||
这个也很容易理解,算是对第一题的升级,第一题有 1 个出现 1次的数,其余出现两次,这个题目中有 2 个出现 1次的数,其余数字出现两次。那么这个题目我们怎么做呢?我们看一下能不能利用第一题中的做法解决。
|
||||
这个也很容易理解,算是对第一题的升级,第一题有 1 个出现一次的数,其余出现两次,这个题目中有 2 个出现一次的数,其余数字出现两次。那么这个题目我们怎么做呢?我们看一下能不能利用第一题中的做法解决。
|
||||
|
||||
### HashSet
|
||||
|
||||
@ -23,6 +23,8 @@
|
||||
|
||||
#### 题目代码
|
||||
|
||||
Java Code:
|
||||
|
||||
```java
|
||||
class Solution {
|
||||
public int[] singleNumber(int[] nums) {
|
||||
@ -31,10 +33,10 @@ class Solution {
|
||||
//存在的则移除
|
||||
if (set.contains(x)) {
|
||||
set.remove(x);
|
||||
continue;
|
||||
//不存在则存入
|
||||
} else {
|
||||
set.add(x);
|
||||
}
|
||||
//不存在存入
|
||||
set.add(x);
|
||||
}
|
||||
//存到数组里,然后返回
|
||||
int[] arr = new int[2];
|
||||
@ -47,6 +49,77 @@ class Solution {
|
||||
}
|
||||
```
|
||||
|
||||
C++ Code:
|
||||
|
||||
```cpp
|
||||
class Solution {
|
||||
public:
|
||||
vector<int> singleNumber(vector<int>& nums) {
|
||||
unordered_set<int> set;
|
||||
for (int x : nums) {
|
||||
//存在的则移除
|
||||
if (set.find(x) == set.end()) {
|
||||
set.insert(x);
|
||||
//不存在则存入
|
||||
} else {
|
||||
set.erase(x);
|
||||
}
|
||||
}
|
||||
//存到数组里,然后返回
|
||||
vector<int> arr;
|
||||
for (int y : set) {
|
||||
arr.push_back(y);
|
||||
}
|
||||
return arr;
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
JS Code:
|
||||
|
||||
```javascript
|
||||
var singleNumber = function(nums) {
|
||||
let set = new Set();
|
||||
for (let x of nums) {
|
||||
//存在的则移除
|
||||
if (set.has(x)) {
|
||||
set.delete(x);
|
||||
//不存在则存入
|
||||
} else {
|
||||
set.add(x);
|
||||
}
|
||||
}
|
||||
//存到数组里,然后返回
|
||||
let arr = [];
|
||||
for (let y of set) {
|
||||
arr.push(y);
|
||||
}
|
||||
return arr;
|
||||
};
|
||||
```
|
||||
|
||||
Python Code:
|
||||
|
||||
```python
|
||||
class Solution:
|
||||
def singleNumber(self, nums: List[int]) -> List[int]:
|
||||
set_ = set()
|
||||
for x in nums:
|
||||
# 存在的则移除
|
||||
if x in set_:
|
||||
set_.remove(x)
|
||||
# 不存在则存入
|
||||
else:
|
||||
set_.add(x)
|
||||
# 存到数组里,然后返回
|
||||
arr = []
|
||||
for y in set_:
|
||||
arr.append(y)
|
||||
return arr
|
||||
```
|
||||
|
||||
|
||||
|
||||
### 位运算
|
||||
|
||||
#### 解析
|
||||
@ -55,53 +128,59 @@ class Solution {
|
||||
|
||||
我们试想一下,如果我们先将元素分成两组,然后每组包含一个目标值,那么异或之后,每组得到一个目标值,那么我们不就将两个目标值求出了吗?
|
||||
|
||||
> 例: **a,b,a,b,c,d,e,f,e,f ** 分组后
|
||||
> 例: **a, b, a, b, c, d, e, f, e, f **
|
||||
>
|
||||
> A组:a, a , b, b, c 异或得到 c
|
||||
> 分组后:
|
||||
>
|
||||
> B组:e, e, f, f, d 异或得到 d
|
||||
> A组:a, a, b, b, c 异或得到 c
|
||||
>
|
||||
> B组:e, e, f, f, d 异或得到 d
|
||||
|
||||
原理懂了,那么我们应该依据什么规则对其进行分类呢?
|
||||
|
||||
c , d 两个不同的数,那么二进制上必定有一位是不同的,那么我们就可以根据这一位(分组位)来将 c , d 分到两个组中,数组中的其他元素,要么在 A 组中,要么在 B 组中。
|
||||
c,d 两个不同的数,那么二进制上必定有一位是不同的,那么我们就可以根据这一位(分组位)来将 c,d 分到两个组中,数组中的其他元素,要么在 A 组中,要么在 B 组中。
|
||||
|
||||
我们应该怎么得到分组位呢?
|
||||
|
||||
我们让 c , d 异或即可,异或运算就是对应位不同时得 1 ,异或之后值为 1 的其中一位则为我们分组。
|
||||
我们让 c,d 异或即可,异或运算就是对应位不同时得 1,异或之后值为 1 的其中一位则为我们分组。
|
||||
|
||||
例 001 ⊕ 100 = 101,我们可以用最右边的 1 或最左边的 1 做为分组位,数组元素中,若我们将最右边的 1 作为我们的分组位,最后一位为 0 的则进入 A 组,为 1 的进入 B 组。
|
||||
例 001 ⊕ 100 = 101,我们可以用最右边的 1 或最左边的 1 做为分组位,数组元素中,若我们将最右边的 1 作为我们的分组位,最后一位为 0 的则进入 A 组,为 1 的进入 B 组。
|
||||
|
||||
那么我们应该怎么借助分组位进行分组呢?
|
||||
|
||||
我们处理 c , d 的异或值,可以仅保留异或值的分组位,其余位变为 0 ,例如 101 变成 001或 100
|
||||
我们处理 c , d 的异或值,可以仅保留异或值的分组位,其余位变为 0 ,例如 101 变成 001或 100。
|
||||
|
||||
为什么要这么做呢?在第二题提到,我们可以根据 a & 1 来判断 a 的最后一位为 0 还是为 1,所以我们将 101 变成 001 之后,然后数组内的元素 x & 001 即可对 x 进行分组 。同样也可以 x & 100 进行分组.
|
||||
为什么要这么做呢?在第二题提到,我们可以根据 a & 1 来判断 a 的最后一位为 0 还是为 1,所以我们将 101 变成 001 之后,然后数组内的元素 x & 001 即可对 x 进行分组 。同样也可以 x & 100 进行分组。
|
||||
|
||||
那么我们如何才能仅保留分组位,其余位变为 0 呢?例 101 变为 001
|
||||
那么我们如何才能仅保留分组位,其余位变为 0 呢?例 101 变为 001。
|
||||
|
||||
我们可以利用 x & (-x) 来保留最右边的 1
|
||||
我们可以利用 x & (-x) 来保留最右边的 1。
|
||||
|
||||
![分组位](https://cdn.jsdelivr.net/gh/tan45du/tan45du.github.io.photo@master/photo/分组位.25gbi25kv7c0.png)
|
||||
|
||||
#### 题目代码:
|
||||
|
||||
Java Code:
|
||||
|
||||
```java
|
||||
class Solution {
|
||||
public int[] singleNumber(int[] nums) {
|
||||
int temp = 0;
|
||||
//小心溢出
|
||||
long temp = 0;
|
||||
//求出异或值
|
||||
for (int x : nums) {
|
||||
temp ^= x;
|
||||
}
|
||||
System.out.println(temp);
|
||||
System.out.println(-temp);
|
||||
//保留最右边的一个 1
|
||||
int group = temp & (-temp);
|
||||
System.out.println(group);
|
||||
long group = temp & (-temp);
|
||||
int[] arr = new int[2];
|
||||
for (int y : nums) {
|
||||
//分组位为0的组,组内异或
|
||||
//分组位为 0 的组,组内异或
|
||||
if ((group & y) == 0) {
|
||||
arr[0] ^= y;
|
||||
//分组位为 1 的组,组内异或
|
||||
//分组位为 1 的组,组内异或
|
||||
} else {
|
||||
arr[1] ^= y;
|
||||
}
|
||||
@ -111,3 +190,79 @@ class Solution {
|
||||
}
|
||||
```
|
||||
|
||||
C++ Code:
|
||||
|
||||
```cpp
|
||||
class Solution {
|
||||
public:
|
||||
vector<int> singleNumber(vector<int>& nums) {
|
||||
//小心 -temp 溢出
|
||||
long temp = 0;
|
||||
//求出异或值
|
||||
for (int x : nums) {
|
||||
temp ^= x;
|
||||
}
|
||||
//保留最右边的一个 1
|
||||
int group = temp & (-temp);
|
||||
vector<int> arr(2, 0);
|
||||
for (int y : nums) {
|
||||
//分组位为 0 的组,组内异或
|
||||
if ((group & y) == 0) {
|
||||
arr[0] ^= y;
|
||||
//分组位为 1 的组,组内异或
|
||||
} else {
|
||||
arr[1] ^= y;
|
||||
}
|
||||
}
|
||||
return arr;
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
JS Code:
|
||||
|
||||
```javascript
|
||||
var singleNumber = function(nums) {
|
||||
let temp = 0;
|
||||
//求出异或值
|
||||
for (let x of nums) {
|
||||
temp ^= x;
|
||||
}
|
||||
//保留最右边的一个 1
|
||||
let group = temp & (-temp);
|
||||
let arr = [0, 0];
|
||||
for (let y of nums) {
|
||||
//分组位为 0 的组,组内异或
|
||||
if ((group & y) == 0) {
|
||||
arr[0] ^= y;
|
||||
//分组位为 1 的组,组内异或
|
||||
} else {
|
||||
arr[1] ^= y;
|
||||
}
|
||||
}
|
||||
return arr;
|
||||
};
|
||||
```
|
||||
|
||||
Python Code:
|
||||
|
||||
```python
|
||||
class Solution:
|
||||
def singleNumber(self, nums: List[int]) -> List[int]:
|
||||
temp = 0
|
||||
# 求出异或值
|
||||
for x in nums:
|
||||
temp ^= x
|
||||
# 保留最右边的一个 1
|
||||
group = temp & (-temp)
|
||||
arr = [0, 0]
|
||||
for y in nums:
|
||||
# 分组位为 0 的组,组内异或
|
||||
if (group & y) == 0:
|
||||
arr[0] ^= y
|
||||
# 分组位为 1 的组,组内异或
|
||||
else:
|
||||
arr[1] ^= y
|
||||
return arr
|
||||
```
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user