LeetCode(初级算法之数组)-只出现一次的数字

这篇博客介绍了如何解决LeetCode的一道题目,即找出数组中只出现一次的数字。博主分享了两种解题方法,一种是通过排序和比较,另一种是利用位运算的异或特性。博客详细解释了位运算的原理,并提供了Python代码实现,包括使用匿名函数的简洁解决方案。此外,博主还总结了从中学到的知识点,如位运算、匿名函数和reduce函数的应用。
摘要由CSDN通过智能技术生成

这是刷LeetCode的第五天,原题地址

题目描述

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

说明

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

示例一

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

示例二

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

解题思路

第一种方法

通过将数组排序,然后遍历数组,每两个对比,如果相同,则进入下一对;如果不相同则返回该对的第一个数。
但这个方法我没有找到如何处理数字出现在最后一对中的情况,即被单着的时候。脑子有点乱,没想清楚数组下标的情况。

第二种方法

从官方题解看到一个解法,用位运算。此题可以采用异或运算,即^。

  • 任何数和 0 做异或运算,结果仍然是原来的数,即a⊕0=a。
  • 任何数和其自身做异或运算,结果是 0,即 a⊕a=0。
  • 异或运算满足交换律和结合律,即a⊕b⊕a=b⊕a⊕a=b⊕(a⊕a)=b⊕0=b。

由于此题有一个是单出来的,所以如果遍历一遍数组,然后一个变量等于数组的首元素,再依次让每个元素与那个变量做异或运算。由于任何数和自身做异或运算的时候等于0,那么相同的数字就被消除掉了,最终得到的结果即为单出来的那个数。

  • 时间复杂度:O(n),其中 nn 是数组长度。只需要对数组遍历一次。
  • 空间复杂度:O(1)。

运行结果

在这里插入图片描述

源代码

class Solution:
    def singleNumber(self, nums: List[int]) -> int:
        result = nums[0]
        for i in range(1,len(nums)):
            result = result^nums[i]
        return result

还有的大佬用匿名函数,一行代码就解决了这个问题。参考如下:

class Solution:
    def singleNumber(self, nums: List[int]) -> int:
        return reduce(lambda x, y: x ^ y, nums)

可见其用时稍微快点,但内存消耗是一样的。
在这里插入图片描述

总结反思

从这个题目中学到了位运算中的异或运算,匿名函数,reduce函数。

  • 位运算。从菜鸟教程中了解到:
    在这里插入图片描述
    在这里插入图片描述
    对于左移动运算符,高位丢弃,低位补0;对于右移动运算符,低位丢弃,高位补0。

  • 匿名函数
    语法:lambda [arg1 [,arg2,…argn]]:expression
    lambda的主体是一个表达式,而不是一个代码块。仅仅能在lambda表达式中封装有限的逻辑进去。lambda函数拥有自己的命名空间,且不能访问自有参数列表之外或全局命名空间里的参数。

  • reduce() 函数
    语法: reduce(function, iterable[, initializer])
    用法: 会对参数序列中元素进行累积,需引入 functools 模块来调用 reduce() 函数。
    函数将一个数据集合(链表,元组等)中的所有数据进行下列操作:用传给 reduce 中的函数 function(有两个参数)先对集合中的第 1、2 个元素进行操作,得到的结果再与第三个数据用 function 函数运算,最后得到一个结果。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值