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在numsi = 0或者numsi = 1时会+1,因为从左边被交换过来的元素一定是已经遍历的过的,而numsi = 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. 下一个排列

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

  • 解题思路

    • 数字倒序排列组成的数字,字典序最大;正序排列的数字序列,字典序最小
    • 从后向前查找第一个正序对,倒序排列的部分字典序已经是最大了,没有调整的余地了
    • 在右边倒序的部分中找到大于numsi的最小数字,和numsi进行交换
    • 此时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个数放到第numsi位置上,如果发现numsi位置上的数已经是numsi了,那么就说明这个数是重复数

  • 代码

    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
相关推荐
晒太羊的猫25 分钟前
hot100动态规划刷题
算法·动态规划
Είναι η κοπέλα1 小时前
显存计算与模型选择:你的显卡能跑多大的模型
人工智能·pytorch·python·开源·conda
weixin_531094691 小时前
heap_4内存管理
java·开发语言·算法
ROSF68681 小时前
2026 仿石漆乳液供应商:市场布局与行业发展态势梳理
大数据·人工智能·python
余额瞒着我当琳1 小时前
红黑树的实现--红黑树的概念、规则、效率、结构、旋转、查找、验证
数据结构·c++·算法
程序员南飞1 小时前
win系统安装minio
java·数据结构·算法
青少儿编程课堂1 小时前
AC自动机多模式串匹配精讲:校园关键词巡检实战解析
c++·python·算法·bfs·信息学竞赛
hhzz1 小时前
【YOLO 入门到精通 04】理解任务与模型家族:7 大 CV 任务与 YOLO26 选型指南
人工智能·python·深度学习·yolo·计算机视觉
Escalating_xu1 小时前
【Python】使用库:标准库、第三方库、pip、项目实战与程序打包
java·python·pip
水獭比特2 小时前
Agent 工具审批不止一个按钮:用 v0.22.1 复盘入口、恢复和副作用
人工智能·python