乐趣区

leetcode136只出现一次的数字

前言

打卡第一天
2019.10.26 日打卡

算法,即解决问题的方法。同一个问题,使用不同的算法,虽然得到的结果相同,但是耗费的时间和资源是不同的。这就需要我们学习算法,找出哪个算法更好。

大家都知道,算法是在面试大厂时不可或缺的一环。而作为普通程序员的我们在工作中大都不怎么接触算法,那么如果以后想要进入大厂工作,提升自己,就必须通过刻意的练习,掌握算法和数据结构,提高编程能力。

“好”算法的标准

对于一个问题的算法来说,之所以称之为算法,首先它必须能够解决这个问题(称为准确性)。其次,通过这个算法编写的程序要求在任何情况下不能崩溃(称为健壮性)。如果准确性和健壮性都满足,接下来,就要考虑最重要的一点:通过算法编写的程序,运行的效率怎么样。

运行效率体现在两方面:

  • 算法的运行时间。(称为“时间复杂度”)
  • 运行算法所需的内存空间大小。(称为“空间复杂度”)

好算法的标准就是:在符合算法本身的要求的基础上,使用算法编写的程序运行的时间短,运行过程中占用的内存空间少,就可以称这个算法是“好算法”。

题目

每天一道 leetcode136. 只出现一次的数字
分类:数组
题目链接: https://leetcode-cn.com/probl…

题目描述

给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现两次。找出那个只出现了一次的元素。
说明:
你的算法应该具有线性时间复杂度。你可以不使用额外空间来实现吗?
示例 1:
输入: [2,2,1]
输出: 1
示例 2:
输入: [4,1,2,1,2]
输出: 4

题解

自己做

  • 思路

使用额外 HashMap 来存储每一个数组元素,最后取出个数为 1 的那一个(看到题目,实在没有啥好思路,这个方法运行效率肯定非常低)

  • 代码实现
class Solution {public int singleNumber(int[] nums) {Map<Integer, Integer> temp = new HashMap<>();

        for (int i : nums) {temp.put(i, temp.get(i) == null ? 1 : temp.get(i) + 1);
        }
        for (int i : nums) {if (temp.get(i) == 1) {return i;}
        }
        return 0;
    }
}
  • 复杂度分析
  1. 时间复杂度:O(n+n) = O(n)。for 循环的时间复杂度是 O(n)。
  2. 空间复杂度:O(n)。hashmap 需要的空间跟 nums 中元素个数相等。
  • 执行结果

最优解:位操作

  • 思路
  1. 任何数与 0 异或为其本身:0 ^ n => n
  2. 相同的数异或为 0:n ^ n => 0
  3. XOR(异或)满足交换律和结合律:a ^ b ^ a = (a ^ a) ^ b = 0 ^ b = b

所以我们只需要将所有的数进行 XOR 操作,得到那个唯一的数字。

  • 代码实现
class Solution {public int singleNumber(int[] nums) {
        int result = 0;
        for(int i : nums) {result^=i;}
        return result;
    }
}
  • 复杂度分析
  1. 时间复杂度:O(n)。只需要将 nums 元素遍历一遍,所以时间复杂度为 nums 中元素的个数。
  2. 空间复杂度:O(1)。

执行结果

结束语

建议大家起码做两遍以上,你可能会发现一些新的技巧或者方法。练习过程中,不是刻意去背这道题的答案,这不是长久之计,先不要参考答案,自己去解决问题,这样才能提高自己的思维能力以及编程能力。

今天是打卡第一天,了解了算法对工作以及今发展的重要性,需要花时间捡起来这部分知识。可能由于是第一次打卡,今天足足花费了两个小时。

想一起打卡进步的朋友们, 欢迎关注笔者公众号: 爱上敲代码, 会定期分享 Java 技术干活, 让枯燥的技术游起来!

退出移动版