【LeetCode每日一题】136. 只出现一次的数字
一、题目
原题地址:136. 只出现一次的数字
二、题解
方法一:遍历数组+Map存储
1.思路及算法
- 遍历数组,存入map中,key是值,value是出现的次数。然后再遍历map,找出次数为1的。
2.代码
/**
* @author : lightupworld
* @description: TODO
* @date 2021/5/20 19:13
*/
public class SingleNumber {
public static int singleNumber(int[] nums) {
if (nums == null || nums.length == 0) {
return 0;
}
Map<Integer,Integer> hashMap = new HashMap<>();
for (int i = 0; i < nums.length; i++ ) {
if (hashMap.containsKey(nums[i])) {
hashMap.put(nums[i], hashMap.get(nums[i])+1 );
} else {
hashMap.put(nums[i], 1);
}
}
//遍历map 取值 = 1
for (Map.Entry<Integer, Integer> entry: hashMap.entrySet()) {
if (entry.getValue() == 1) {
return entry.getKey();
}
}
return 0;
}
public static void main(String[] args) {
int[] nums = new int[]{4, 1, 2, 1, 2};
System.out.println(singleNumber(nums));
}
}
// 更优的写法
class SingleNumber {
public int singleNumber(int[] nums){
Map<Integer, Integer> hashMap = new HashMap<>();
for(Integer i : nums){
Integer count = hashMap.get(i);
count = count == null ? 1 : ++count;
hashMap.put(i, count);
}
for (Integer i : hashMap.keySet()) {
Integer count = hashMap.get(i);
if (count == 1) {
return i;
}
}
return -1; // can't find it.
}
}
3.复杂度分析
- 时间复杂度:O(n) ,n是数组的长度,需要遍历一次。
- 空间复杂度: O(n),需要额外开辟一个map存储数据。
4.注意事项
i++
与++i
的区别:i = 1 a = i++ : 先赋值 后运算。 先 a = i = 1,再 i++ => 2 a = ++i : 先运算 后赋值。 先是 i自加 => 2, 再 a = i =2
- 常用的两种遍历Map的方法
1.同时遍历 key value Map<Integer, Integer> map = new HashMap<>(); for (Map.Entry<Integer, Integer> entry : map.entrySet()) { entry.getKey(); entry.getValue(); } 2.单独遍历key value for (Integer key : map.keySet()) { System.out.println(key); } for (Integer value : map.values()) { System.out.println(value); }
方法二:异或运算
1.思路以及算法
- 这题拿到手,第一反应是用hash表,没有思考细节,只是觉得hash表肯定是可以搞定的,但是空间复杂度是 O(n),不满足题意。
- 继续思考,如何再继续降低复杂度呢? 想到了排序。使用快排,复杂度 O(nlogn),如何能把时间复杂度降到 O(n)
- 反复看了好几篇题目,找到了一个很重要的信息:除了某个元素只出现一次以外,其余每个元素均出现两次。 觉得这是个突破口!!!!——异或运算!
- 异或运算重要性质:
异或运算是基于二进制的位运算,采用符号XOR或者^来表示,运算规则是就与二进制,如果是同值取0、异值取1。 简单的理解就是不进位加法,例如1+1=0,0+0=0,1+0=0; 重要性质: 1.交换律 可以任意交换运算因子,结果不变。 2.结合律 (a^b)^c=a^(a^c) 3.对于任何数x,都有x^x=0,x^0=x,同自己求异或运算为0,同0求异或运算结果为自己
2.代码
class SingleNumber {
public int singleNumber(int[] nums){
int single = 0;
for (int n: nums) {
single ^= n;
}
return single
}
public static void main(String[] args) {
int[] nums = new int[]{4, 1, 2, 1, 2};
System.out.println(singleNumber(nums));
// 0 ^ 4 = 4 ; 4 ^ 1 = 5 ; 5^2=7 ; 7 ^ 1 = 6 ; 6 ^ 2 = 4
/* 0 0 0 1 0 0 1 0 1 1 1 1 1 1 0
1 0 0 0 0 1 0 1 0 0 0 1 0 1 0
= 1 0 0 4 1 0 1 5 1 1 1 7 1 1 0 = 6 1 0 0
*/
}
}
3.复杂度分析
- 时间复杂度:O(n)
- 空间复杂度:O(1)
https://leetcode-cn.com/problems/single-number/solution/hua-jie-suan-fa-136-zhi-chu-xian-yi-ci-de-shu-zi-b/
https://blog.csdn.net/tjcyjd/article/details/11111401