当前位置: 首页 > news >正文

Day13,Hot100(数学技巧)

136. 只出现一次的数字

在这里插入图片描述

  1. 两个相同的数异或 --> 0
  2. 0 与任何数异或 --> 结果不变,仍然为数本身
  3. 异或满足交换律和结合律

eg

  • [2,2,1]
  • x^2 = 2
  • 2^2 = 0
  • 0^1 = 1
class Solution:
    def singleNumber(self, nums: List[int]) -> int:
        x = 0
        for num in nums:
            x ^= num
        return x

169. 多数元素

在这里插入图片描述

解析

class Solution:
    def majorityElement(self, nums: List[int]) -> int:
        votes = 0
        x = 0
        for num in nums:
            # 当票数为0时, 假设当前数为众数
            if votes == 0:
                x = num
            # 当前数为假设的众数时, +1
            if x == num:
                votes += 1
            else:
                votes -= 1
        return x

75. 颜色分类

在这里插入图片描述
要求原地操作,且只扫描一次

三路快排

  • 将区间划分为三个区间
  • 区间1:小于 partition 的部分
  • 区间2:等于 partition 的部分
  • 区间3:大于 partition 的部分

如果设 partition = 1,那么结果刚好是我们需要的

  1. 初始化
    • 区间1, all in nums [0 .. zero] = 0,闭区间
    • 区间2, all in nums (zero .. i) = 1,开区间
    • 区间3, all in nums [two .. n-1] = 2,闭区间
    • 为了保证初始时三个区间都为空, zero = -1two = n
  2. nums[i] == 0,需要放到区间 1 的末尾
    • zero 移动一个位置用于与 i 交换
    • 因为第一个区间, zero一定是指向最后一个 0
    • 之后 i++,因为区间2中, i 是在zero右边
  3. nums[i] ==1,需要放到区间 2 的末尾
    • 而 i 刚好就是区间 2 的末尾
    • 由于是开区间, 区间 2 不包含 i,所以i++
  4. nums[i] ==2,需要放到区间 2 的开头
    • 将 two 移动一个位置用于交换
    • 此时 i 不用 ++,因为原来的 nums[two] 值是多少,还没有遍历
class Solution:
    def swap(self, nums, index1, index2):
        nums[index1], nums[index2] = nums[index2], nums[index1]

    def sortColors(self, nums: List[int]) -> None:
        n = len(nums)

        # 区间1, all in nums[0 .. zero] = 0
        # 区间2, all in nums(zero .. i) = 1
        # 区间3, all in nums[two .. n-1] = 2

        zero = -1  # 保证区间1和2,在初始时为空
        two = n  # 保证区间3,在初始时为空
        i = 0
        while i < two:
            if nums[i] == 0:
                zero += 1
                self.swap(nums, i, zero)
                i += 1  # 因为 i 在zero的右侧
            elif nums[i] == 1:
                i += 1
            else:
                two -= 1
                self.swap(nums, i, two)

冒泡 O(n^2)

class Solution:
    def sortColors(self, nums: List[int]) -> None:
        """
        Do not return anything, modify nums in-place instead.
        """
        n = len(nums)
        for i in range(n - 1):  # 进行 n-1 轮冒泡
            swapped = False  # 用于优化,如果本轮没有交换,则提前结束
            for j in range(n - 1 - i):  # 每轮比较前 n-1-i 个元素
                if nums[j] > nums[j + 1]:  # 相邻元素交换
                    nums[j], nums[j + 1] = nums[j + 1], nums[j]
                    swapped = True
            if not swapped:  # 如果没有发生交换,说明已经有序,提前终止
                break
        return nums

31. 下一个排列

在这里插入图片描述

排列的顺序就是DFS的顺序

每个分支的最后一个分支,一定是降序的(下图的14320中的 4320

也就是是说,当遇到降序分支后,就需要转移到下一个分支了

而下一个分支,一定是升序的(每次选当前可选的最小值 2 0134)

如何确定下一个分支开头元素?

  • 1 4320,逆序遍历,0–>2–>3–>4–>1,发现逆序部分
  • 下一个点的开头就是,逆序部分中第一个大于它的元素(2
  • 交换 1 和 2
  • 然后 sort 2后面的部分 —— 2 0134
    在这里插入图片描述
class Solution:
    def nextPermutation(self, nums: List[int]) -> None:
        n = len(nums)
        if n <= 1:
            return nums

        # 从后往前遍历, 找逆序序列
        i = n-2
        while i >= 0 and nums[i] >= nums[i+1]:
            i -= 1
        
        if i < 0:
            # 说明整个序列都是逆序的, 排列已经到最后一个了
            left = 0
            right = n -1 
        else:
            j = n-1
            while i < j and nums[i] >= nums[j]:
                j -= 1
            nums[i], nums[j] = nums[j], nums[i]
            left = i + 1
            right = n -1 

        while left < right:
            nums[left], nums[right] = nums[right], nums[left]
            left += 1
            right -= 1

287. 寻找重复数

在这里插入图片描述

参考<142.环形链表II>,相当于我们要找到环的入口

对于例子 [1, 3, 4, 2, 2],有如下映射:

  • 0->1

  • 1->3

  • 3->2

  • 2->4

  • 4->2

可以构成下面的带环链表,而重复元素就是环的入口
在这里插入图片描述

  1. 快慢指针相遇后
  2. head 和 慢指针一起走,会在入口相遇
class Solution:
    def findDuplicate(self, nums: List[int]) -> int:
        slow = 0
        fast = 0

        while True:
            fast = nums[fast]
            fast = nums[fast]
            slow = nums[slow]
            if slow == fast:
                head = 0
                while head != slow:
                    head = nums[head]
                    slow = nums[slow]
                return head

相关文章:

  • ARM 架构下 cache 一致性问题整理
  • Window C++模拟单片机控制TFT屏幕和SD卡
  • etcd心跳机制与存储性能影响深度分析
  • 三元组排序(acwing)c++
  • 26、IO流(只是小入门)
  • netty如何处理粘包半包
  • 股市能量场理论Python实战指南
  • ubuntu Linux 正确设置中文环境的方法
  • 计算机基础:二进制基础03,二进制数的位基和位权
  • 基于SpringBoot和PostGIS的省域“地理难抵点(最纵深处)”检索及可视化实践
  • 开篇词 | Go 项目开发极速入门课介绍
  • Redis学习笔记系列(一)——Redis简介及安装
  • 上手大模型应用LangChain
  • Android平台GB28181设备接入模块之SmartGBD
  • pandas 数据透视表
  • Win10环境借助DockerDesktop部署单节点Redis6
  • SwiftUI之状态管理全解析
  • tcc编译器教程1 配置tcc编译器环境
  • Python面向对象编程入门:从类与对象到方法与属性
  • Deepseek 模型蒸馏
  • 做医疗竞价网站/百度指数批量查询工具
  • 开发公司房屋维修办法/百度seo怎么收费
  • 做市场调查的网站免费/福州关键词排名优化
  • 国外网站后台模板/上海关键词自动排名
  • 网站设计做什么的/大作设计网站
  • 做网站付费流程/网站建设的技术支持