Python题解Leetcode Hot100之技巧

1. 只出现一次的数字

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

  • 解题思路
    使用异或运算符。因为相同的数异或后为 0,任何数与 0 异或是其本身,所以将所有元素进行异或操作,最终结果即为只出现一次的元素。
    时间复杂度:O(n), 空间复杂度O(1)

  • 代码

    python 复制代码
    class Solution:
        def singleNumber(self, nums: List[int]) -> int:
            n = len(nums)
            res = 0
            for i in nums:
                res = res ^ i
            return res

2. 多数元素

  • 题目描述
    给定一个大小为 n 的数组,找到其中的多数元素。多数元素是指在数组中出现次数大于 ⌊n / 2⌋ 的元素。

  • 解题思路
    根据提议可知,多数元素出现的次数大于其他所有元素出现次数之和。使用摩尔投票算法(Boyer-Moore Voting Algorithm)。遍历数组,维护一个候选多数元素和计数器,遇到相同元素则计数加一,不同则减一,计数为零时更换候选元素。最终的候选元素即为多数元素。
    时间复杂度:O(n), 空间复杂度O(1)

  • 代码

    python 复制代码
    class Solution:
        def majorityElement(self, nums: List[int]) -> int:
            res = nums[0]
            count = 1
            for i in nums[1:]:
                if i == res:
                    count += 1
                else:
                    count -= 1
                if count == 0:
                    res = i
                    count = 1
            return res

3. 颜色分类

  • 题目描述
    给定一个包含红色、白色和蓝色、共 n 个元素的数组,原地对它们进行排序,使得相同颜色的元素相邻,并按照红色、白色、蓝色顺序排列。这里使用整数 0、 1 和 2 分别表示红色、白色和蓝色。

  • 解题思路
    使用双指针方法,一个指针用于扫描数组,另两个指针分别维护红色区域的边界和蓝色区域的边界,遍历数组时,根据当前元素调整指针和元素的位置。
    只要是0就把他移动到最左边的区域,是2就把他移动到最右边的区域,最后中间区域一定剩下的是1;
    注意用于扫描数组的指针i在nums[i] = 0或者nums[i] = 1时会+1,因为从左边被交换过来的元素一定是已经遍历的过的,而nums[i] = 2时,交换完之后i不会加1,因为从右边交换过来的元素时全新的没有见过;
    时间复杂度:O(n), 空间复杂度O(1)

  • 代码

    python 复制代码
    class Solution:
        def sortColors(self, nums: List[int]) -> None:
            """
            Do not return anything, modify nums in-place instead.
            """
            
            n = len(nums)
            zero = -1
            two = n
            i = 0
            while i < two:
                if nums[i] == 1:
                    i += 1
                elif nums[i] == 0:
                    zero += 1
                    nums[zero], nums[i] = nums[i], nums[zero]
                    i += 1
                else:
                	# 注意nums[i] = 2时,i不加1
                    two -= 1
                    nums[two], nums[i] = nums[i], nums[two]

4. 下一个排列

  • 题目描述
    实现获取下一个排列的函数,算法需要将给定数字序列重新排列成字典序中下一个更大的排列。如果不存在下一个更大的排列,则将其排列成最小的排列(即升序排列)。

  • 解题思路

    • 数字倒序排列组成的数字,字典序最大;正序排列的数字序列,字典序最小
    • 从后向前查找第一个正序对,倒序排列的部分字典序已经是最大了,没有调整的余地了
    • 在右边倒序的部分中找到大于nums[i]的最小数字,和nums[i]进行交换
    • 此时i右边仍是倒序,翻转成正序,正序是字典序最小的排列方式
  • 代码

    python 复制代码
    class Solution:
        def nextPermutation(self, nums: List[int]) -> None:
            """
            Do not return anything, modify nums in-place instead.
            """
            # 数字倒序排列组成的数字,字典序最大
    
            def reverse(nums, left, right):
                l = left
                r = right
                while l <= r:
                    nums[l], nums[r] = nums[r], nums[l]
                    l += 1
                    r -= 1
            n = len(nums)
            if n <= 1:
                return nums
            # 从后向前查找第一个正序对,倒序排列的部分字典序已经是最大了,没有调整的余地了
            for i in range(n - 2, -1, -1):
                if nums[i] < nums[i + 1]:
                    j = n - 1
                    # 在右边倒序的部分中找到大于nums[i]的最小数字,和nums[i]进行交换
                    while j > i:
                        if nums[j] > nums[i]:
                            nums[i], nums[j] = nums[j], nums[i]
                            # 此时i右边仍是倒序,翻转成正序,正序是字典序最小的排列方式
                            reverse(nums, i + 1, n - 1)
                            return 
                        j -= 1
            # 如果到了这一步说明整个序列都是倒序,那么直接翻转即可
            reverse(nums, 0, n - 1)

5. 寻找重复数

  • 题目描述
    给定一个包含 n + 1 个整数的数组,其数字都在 1 到 n 之间(包括 1 和 n),可知至少存在一个重复的整数。假设只有一个重复的整数,找出这个重复的数。

  • 解题思路
    原地哈希,将第i个数放到第nums[i]位置上,如果发现nums[i]位置上的数已经是nums[i]了,那么就说明这个数是重复数

  • 代码

    python 复制代码
    class Solution:
        def findDuplicate(self, nums: List[int]) -> int:
            n = len(nums)
            i = 0
            while i < n:
                cur_num = nums[i]
                if cur_num != i:
                	# 如果nums[nums[i]]处不是nums[i],那么交换nums[nums[i]]和nums[i]
                    if nums[cur_num] != cur_num:
                        nums[cur_num], nums[i] = nums[i], nums[cur_num]
                    else:
                        return cur_num
                else:
                    i += 1
相关推荐
FreakStudio3 分钟前
全网最适合入门的面向对象编程教程:41 Python 常用复合数据类型-队列(FIFO、LIFO、优先级队列、双端队列和环形队列)
python·嵌入式·面向对象·电子diy
pzn250630 分钟前
C语言实现经典排序算法
数据结构·算法·排序算法
星眺北海1 小时前
【后端】使用uWSGI部署django项目
linux·python·django·uwsgi
探数数据2 小时前
使用python对接空号检测API接口
前端·python·yapi
小鹿( ﹡ˆoˆ﹡ )2 小时前
Python中的“for循环”:探索其无限潜力
开发语言·python
Lanthanmum2 小时前
P1505 [国家集训队] 旅游
数据结构·算法
阿史大杯茶2 小时前
Codeforces Round 968 (Div. 2 ABCD1D2题) 视频讲解
数据结构·c++·算法
不想敲代码!!!2 小时前
爆改YOLOv8 | 利用CPA-Enhancer提高低照度物体检测(适用于雨,雪,雾天)
人工智能·pytorch·python·yolo·目标检测·yolov8
猿饵块2 小时前
ros2--jupyter
ide·python·jupyter
景天科技苑2 小时前
【python】如何通过Python中的http.server搭建文件上传下载服务
开发语言·python·http·python文件上传下载·http.server