【LeetCode每日一题】136. 只出现一次的数字

【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=00+0=01+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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值