lt.136. 只出现一次的数字
[案例需求]
[思路分析一, 排序后遍历]
- 排序后进行遍历, 步进长度为2 (因为题目给定, 最多两个重复),
- 所以我们每次遍历的数要么是两次重复的后一个数, 要么是唯一的一个数的后面的一个数
[代码实现]
class Solution {
public int singleNumber(int[] nums) {
Arrays.sort(nums);
int len = nums.length;
for(int i = 1; i < len; i += 2;){
if(nums[i] != nums[i - 1])return nums[i - 1];
}
return nums[len - 1];
}
}
# 另一种写法
class Solution {
public int singleNumber(int[] nums) {
Arrays.sort(nums);
int i = 0;
while(i + 1 < nums.length && nums[i] == nums[i+1]){
i = i + 2;
}
return nums[i];
}
}
[思路分析三, 集合]
- 使用HashSet, 事先添加一个元素,
- 然后遍历数组和HashSet中的值进行比较(使用set.contains(x)).
- 如果发现重复(add一个值返回false, 或者说用contains方法判断), hashSet中删除这个值
- 那么遍历结束后, 根据题目中仅有一个值重复, hashset中理应当只剩下一个唯一的元素
[代码实现]
class Solution {
public int singleNumber(int[] nums) {
Set<Integer> set = new HashSet<>();
set.add(nums[0]);
for(int i = 1; i < nums.length; i++){
if(!set.add(nums[i])){
set.remove(nums[i]);
}else{
set.add(nums[i]);
}
}
int res = 0;
for(int x : set){
res = x;
}
return res;
}
}
[思路分析四, 哈希表]
[代码实现]
class Solution {
public int singleNumber(int[] nums) {
if (nums.length == 1) {
return nums[0];
}
HashMap<Integer,Integer> map = new HashMap<Integer,Integer>();
for (int x : nums) {
map.put(x , map.getOrDefault(x,0) + 1);
}
for (int y : map.keySet()) {
if(map.get(y) == 1){
return y;
}
}
return 0;
}
}
[思路分析五, HashSet + 求和]
[代码示例]
class Solution {
public int singleNumber(int[] nums) {
if (nums.length == 1){
return nums[0];
}
HashSet<Integer> set = new HashSet<>();
int setsum = 0;
int numsum = 0;
for (int x : nums) {
numsum += x;
if (!set.contains(x)) {
setsum += x;
}
set.add(x);
}
return setsum * 2 - numsum;
}
}
[思路分析五, 位运算]
异或解法:异或运算满足交换律,a^b^a=a^a^b=b ,因此ans相当于nums[0]^nums[1]^nums[2]^nums[3]^nums[4]..... 然后再根据交换律把相等的合并到一块儿进行异或(结果为0),然后再与只出现过一次的元素进行异或,这样最后的结果就是,只出现过一次的元素(0^任意值=任意值)
[代码实现]
class Solution {
public int singleNumber(int[] nums) {
int result = 0;
for (int i = 0; i < nums.length; i++){
result ^= nums[i];
}
return result;
}
}
137. 只出现一次的数字 II
[案例需求]
[思路分析一, 哈希表法]
[代码实现]
class Solution {
public int singleNumber(int[] nums) {
Map<Integer, Integer> map = new HashMap<>();
for(int i = 0; i < nums.length; i++){
map.put(nums[i], map.getOrDefault(nums[i], 0) + 1);
}
for(int key : map.keySet()){
if(map.get(key) == 1)return key;
}
return -1;
}
}
[思路分析二, HashSet + 求和法]
[代码实现]
class Solution {
public int singleNumber(int[] nums) {
HashSet<Integer> set = new HashSet<>();
long sumset = 0;
long sumnum = 0;
for (int x : nums) {
sumnum += x;
if (set.contains(x)) {
continue;
}
sumset += x;
set.add(x);
}
return (int)((3 * sumset - sumnum) / 2);
}
}
[思路分析三, 位运算]
- 我们在第一题中有个利用异或求解的方法,但是这个题目是出现三次,我们则不能利用直接异或来求解
-
[代码示例]
class Solution {
public int singleNumber(int[] nums) {
int res = 0;
for(int i = 0; i < 32; i++){
int count = 0;
for (int j = 0; j < nums.length; j++) {
if ((nums[j] >> i & 1) == 1) {
count++;
}
}
if (count % 3 != 0) {
res = res | 1 << i;
}
}
return res;
}
}
lt.260. 只出现一次的数字 III
[案例需求]
[思路分析一, 哈希表法]
[代码实现]
class Solution {
public int[] singleNumber(int[] nums) {
Set<Integer> set = new HashSet<>();
set.add(nums[0]);
for(int i = 1; i < nums.length; i++){
if(!set.add(nums[i])){
set.remove(nums[i]);
}else{
set.add(nums[i]);
}
}
int[] res = new int[2];
int index = 0;
for(int x : set){
res[index++] = x;
}
return res;
}
}
[思路分析二, 位运算]
[代码实现]
class Solution {
public int[] singleNumber(int[] nums) {
int temp = 0;
for (int x : nums) {
temp ^= x;
}
int group = temp & (-temp);
System.out.println(group);
int[] arr = new int[2];
for (int y : nums) {
if ((group & y) == 0) {
arr[0] ^= y;
} else {
arr[1] ^= y;
}
}
return arr;
}
}
|