每日一道算法题-leetcode136-只出现一次的数字

前言

打卡第一天
2019.10.26日打卡

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

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

“好”算法的标准

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

运行效率体现在两方面:

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

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

题目

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

题目描述

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

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

示例 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技术干活,让枯燥的技术游起来!

扫码关注

【本文最先发布于此站,转载请注明来源】: http://coderluo.top

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值