Leetcode题库-只存在一次的数字(java语言版)

题目描述:

给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现两次。找出那个只出现了一次的元素。

说明:

你的算法应该具有线性时间复杂度。 你可以不使用额外空间来实现吗?

示例 1:

输入: [2,2,1]
输出: 1

示例 2:

输入: [4,1,2,1,2]
输出: 4

   本题属于简单题,思路有两个:

   第一个思路:查找表map,我首先想到的是用map,存储数组元素和出现的次数,然后遍历map,判断如果键对应的值为1,则将该键输出。

   第二种思路:异或运算符。这个真的是一个非常好的方法,我没有想到,借鉴leetcode评论中的思路。太巧妙了,因为异或运算符有几个特性:      1>满足 交换律:a ^ b ^ c <=> a ^ c ^ b

                               2>任何数与0异或为任何数 0 ^ n => n

                               3>相同的数异或为0: n ^ n => 0

   有了这几个特性,这个题特别太容易求解,因为题目说,数组中只有一个数是出现一次其余全是两次,这样两次的异或后全为0,0在于出现一次的异或,全为本身,最后输出这个出现一次的即可。

代码如下:

     第一种思路:

//        第一种方法用查找表来存储元素和出现的次数,当次数为1时则返回这个元素。
        Map<Integer,Integer> map =new HashMap <> (  );
        for (int i=0;i<a.length;i++){
            if (map.containsKey ( a[i] )){
                map.put ( a[i],map.get ( a[i] )+1 );
            }else {
                map.put ( a[i],1 );
            }
        }
       for (int num:map.keySet ()){
            if (map.get ( num )==1){
                System.out.println(num);
            }
       }

执行结果:

执行用时:

第二种方法:

  //借鉴评论里的方法,根本没有想到这道题使用异或运算符,很忽视啊。
//        交换律:a ^ b ^ c <=> a ^ c ^ b
//
//        任何数于0异或为任何数 0 ^ n => n
//
//        相同的数异或为0: n ^ n => 0
          int result=0;
          for (int i=0;i<a.length;i++){
              result^=a[i];
          }
          System.out.println(result);

执行用时:

     总结:这道题用异或运算特变简便,代码特别少,时间复杂度特别低。以前学习真没重视这么重要,强大的东西。这就证明了一点,那些越不重视的东西,在某些时候还是最重要的。永远啊不要轻视那些看似没用的东西。

2019-4-2

发布了43 篇原创文章 · 获赞 6 · 访问量 6655

猜你喜欢

转载自blog.csdn.net/weixin_37850160/article/details/88979641