[leetcode] 二分算法

news2025/6/5 6:00:43

本文介绍算法题中常见的二分算法。二分算法的模板框架并不复杂,但是初始左右边界的取值以及左右边界如何向中间移动,往往让我们头疼。本文根据博主自己的刷题经验,总结出四类题型,熟记这四套模板,可以应付大部分二分算法题。

简言之,这四类题型分别是:
1.手动实现lower_bound/upper_bound,python中是bisect_left/bisect_right;
2.二分答案;
3.山脉数组;
4.旋转数组。

下面详细介绍这四种题型,介绍中的题单来自leetcode 灵神题单:https://leetcode.cn/discuss/post/3579164/ti-dan-er-fen-suan-fa-er-fen-da-an-zui-x-3rqn/

一、手动实现二分库函数

实现方法有三种,1)闭区间写法;2)左闭右开区间写法;3)开区间写法。这里的开闭区间指的是左右边界的取值是否包括数组的左右端点。三种写法可以参考灵神题解:https://leetcode.cn/problems/find-first-and-last-position-of-element-in-sorted-array/solutions/1980196/er-fen-cha-zhao-zong-shi-xie-bu-dui-yi-g-t9l9/。具体选用哪一种写法,根据个人喜好。博主使用左闭右开写法较多,所有下面的代码都是左闭右开的写法。

34. 在排序数组中查找元素的第一个和最后一个位置 [Medium]
35. 搜索插入位置 [Simple]
704. 二分查找 [Simple]
744. 寻找比目标字母大的最小字母 [Simple]
2529. 正整数和负整数的最大计数 [Simple]

# 34. 在排序数组中查找元素的第一个和最后一个位置
class Solution:
    def searchRange(self, nums: List[int], target: int) -> List[int]:
        
        def lower_bound(t):
            l,r=0,len(nums)
            while l<r:
                mid=(l+r)//2
                if nums[mid]>=t:
                    r=mid
                else:
                    l=mid+1
            return l
            
        l1=lower_bound(target)
        if l1==len(nums) or nums[l1]!=target:
            return [-1,-1]
        l2=lower_bound(target+1)
        return [l1,l2-1]

        # 库函数写法
        l=bisect_left(nums,target)
        r=bisect_right(nums,target)
        if l==r:
            return [-1,-1]
        return [l,r-1]

这里有几个容易混淆的点,
1.为什么是l<r不是l<=r

  • while结束的条件是l==r,且当l==r时,不会再去执行while中的逻辑。我们的右边界是len(nums),是不能索引的。所以只能用l<r,如果用l<=r,那么就会访问下标len(nums),导致越界。

2.为什么是nums[mid]>=t,不是nums[mid]>t?为什么是r=mid,不是r=mid-1?为什么是l=mid+1,不是l=mid

  • 对于各种类型的二分算法题,我们只需要考虑当二分到只剩两个数时,怎么写可以找到目标且退出while循环。只剩两个数时,这个时候mid总是指向前一个数。如果前一个数是我们要找的数,那么只能将rl逼近,触发终止条件;如果后一个数是我们要找的,那么只能将lr逼近,触发终止条件。所以只能用上面的写法,其他写法会导致死循环,永远退出不了while循环。

下面的题目将直接使用二分库函数,必要时需要将原数组先排序。
2300. 咒语和药水的成功对数 [Medium]
1385. 两个数组间的距离值 [Simple]
2389. 和有限的最长子序列 [Simple]
1170. 比较字符串最小字母出现频次 [Medium]
2080. 区间内查询数字的频率 [Medium]
3488. 距离最小相等元素查询 [Medium]
2563. 统计公平数对的数目 [Medium]
2070. 每一个查询的最大美丽值 [Medium]
1818. 绝对差值和 [Medium]
911. 在线选举 [Medium]
658. 找到 K 个最接近的元素 [Medium]
1150. 检查一个数是否在数组中占绝大多数 [Simple]

# 2563. 统计公平数对的数目
class Solution:
    def countFairPairs(self, nums: List[int], lower: int, upper: int) -> int:
        nums.sort()
        n=len(nums)
        ans=0
        for i,x in enumerate(nums):
            # 不要用这种写法,bisect_left(nums[i:],lower-x),会超时
            low=bisect_left(nums,lower-x,i+1,n)
            high=bisect_right(nums,upper-x,i+1,n)
            ans+=high-low
        return ans

bisect_left 和 bisect_right 支持给定区间内的搜索。

# 2070. 每一个查询的最大美丽值
class Solution:
    def maximumBeauty(self, items: List[List[int]], queries: List[int]) -> List[int]:
        items.sort(key=lambda x:x[0])
        for i in range(1,len(items)):
            items[i][1]=max(items[i-1][1],items[i][1])
        
        for i,q in enumerate(queries):
            # bisect_right可以加lambda参数
            h=bisect_right(items,q,key=lambda x:x[0])
            queries[i]=items[h-1][1] if h else 0
        return queries

bisect_left可以像sorted函数一样,接收lambda函数指定在多维列表中的某一维上搜索。

上面这些题绝大多数都是题目给出两个数组,对其中一个数组做一些处理,然后针对另外一个数组中的每个元素,在处理过的数组中二分搜索。

下面几题都是在键值对上做二分搜索,方法巧妙:
1146. 快照数组 [Medium]
981. 基于时间的键值存储 [Medium]
3508. 设计路由器 [Medium]

# 1146. 快照数组
class SnapshotArray:

    def __init__(self, length: int):
        self.cur_snap_id=0
        self.history=defaultdict(list)
        
    def set(self, index: int, val: int) -> None:
        self.history[index].append((self.cur_snap_id,val))

    def snap(self) -> int:
        self.cur_snap_id+=1
        return self.cur_snap_id-1

    def get(self, index: int, snap_id: int) -> int:
        k=bisect_right(self.history[index],snap_id,key=lambda x:x[0])
        return 0 if not k else self.history[index][k-1][1]

未完成:
LCP 08. 剧情触发时间 [Medium]
1182. 与目标颜色间的最短距离 [Medium]
2819. 购买巧克力后的最小相对损失 [Medium]
1287. 有序数组中出现次数超过 25% 的元素 [Simple]

二、二分答案

这类题型,我们能够通过题目得出答案的范围,然后在答案的范围内做二分搜索,最终找出确切的答案。

首先,根据题目确定答案的左右边界,也就是答案的最小值和最大值,如果不能快速的确定答案的最小值和最大值,可以直接用题目中的边界条件,例如:-105, 105。然后,对答案范围做二分搜索,判断给定的中间值是否满足题干要求。这里,我们要定义一个check(x)函数,x即每次二分的中间值,check(x)==True即满足题干要求。这类题目的难点就在于,如何实现check(x)函数。

1) 求最小:

1283. 使结果不超过阈值的最小除数 [Medium]
2187. 完成旅途的最少时间 [Medium]
1011. 在 D 天内送达包裹的能力 [Medium]
875. 爱吃香蕉的珂珂 [Medium]
3296. 移山所需的最少秒数 [Medium]
475. 供暖器 [Medium]
2594. 修车的最少时间 [Medium]
1482. 制作 m 束花所需的最少天数 [Medium]

避免浮点数:

1870. 准时到达的列车最小时速 [Medium]
3453. 分割正方形 I [Medium]

# 1283. 使结果不超过阈值的最小除数
class Solution:
    def smallestDivisor(self, nums: List[int], threshold: int) -> int:
        
        def check(x):
            s=0
            for y in nums:
                s+=ceil(y/x)
            if s>threshold:
                return False
            else:
                return True
        
        # 求什么,二分什么
        l,r=1,max(nums)
        ans=0
        while l<=r:
            mid=(l+r)//2
            if check(mid):
                r=mid-1
                ans=mid
            else:
                l=mid+1
        return ans

跟第一类题型一样,可能我们又会有疑问,
1.为什么while的条件是l<=r,不是l<r?

  • 在这类题型中,l和r分别是答案的最小值和最大值,它们都是有可能成为最终答案的,所以它们都可能进while循环执行逻辑,因此条件是l<=r。如果是l<r,那么当l==r时,触发结束条件,就没机会进while循环执行逻辑了。

2.为什么是r=mid-1,不是r=mid?

  • 跟第一类题型一样,我们只需要考虑只剩两个数时的情况。只剩两个数时,mid总是取前一个数。如果前一个数是最终答案,那么r=mid-1,此时r<l,触发结束条件,循环结束;如果后一个数是最终答案,那么l=mid+1,此时l==r,再进一次while循环,执行逻辑跟刚才一样,触发结束条件,循环结束。其他写法可能会导致死循环,无法退出while循环。

注意,

  1. 这题右边界取max(nums)即可,当然也可以直接取题干中nums[i]的范围作为左右边界:1 <= nums[i] <= 10^6
  2. 在check(x)==True时,要即时记下答案
  3. 求最小,所以是从大往小逼近,因此在check(x)==True时,右边界变小。

未完成:
3048. 标记所有下标的最早秒数 I [Medium]
2604. 吃掉所有谷子的最短时间 [Hard]
2702. 使数字变为非正数的最小操作次数 [Hard]

2) 求最大:

求最大跟求最小框架基本一样,唯一的区别在于,求最大是在check(x)==True时,左边界变大。

2226. 每个小孩最多能分到多少糖果 [Medium]
275. H 指数 II [Medium]
2982. 找出出现至少三次的最长特殊子字符串 II [Medium]
2576. 求出最多标记下标 [Medium]
1898. 可移除字符的最大数目 [Medium]
1802. 有界数组中指定下标处的最大值 [Medium]
1642. 可以到达的最远建筑 [Medium]

# 2226. 每个小孩最多能分到多少糖果
class Solution:
    def maximumCandies(self, candies: List[int], k: int) -> int:
        if sum(candies)<k:
            return 0
            
        def check(x):
            s=0
            for c in candies:
                s+=c//x
            if s>=k:
                return True
            else:
                return False
        
        l,r=1,max(candies)
        ans=1
        while l<=r:
            mid=(l+r)//2
            if check(mid):
                l=mid+1
                ans=mid
            else:
                r=mid-1
        return ans

未完成:
2861. 最大合金数 [Medium]
3007. 价值和小于等于 K 的最大数字 [Medium]
2141. 同时运行 N 台电脑的最长时间 [Hard]
2258. 逃离火灾 [Hard]
2071. 你可以安排的最多任务数目 [Hard]
LCP 78. 城墙防线 [Medium]
1618. 找出适应屏幕的最大字号 [Medium]
1891. 割绳子 [Medium]
2137. 通过倒水操作让所有的水桶所含水量相等 [Medium]
644. 子数组最大平均数 II [Hard]
3143. 正方形中的最多点数 [Medium]
1648. 销售价值减少的颜色球 [Medium]

3) 第K小/大

此类问题,本质还是二分答案。只不过在check(x)函数中,返回值都是跟K比较。

  • 第 k 小等价于:求最小的 x,满足 ≤x 的数至少有 k 个。
  • 第 k 大等价于:求最大的 x,满足 ≥x 的数至少有 k 个。

668. 乘法表中第 K 小的数 [Hard]
378. 有序矩阵中第 K 小的元素 [Medium]
719. 找出第 K 小的数对距离 [Hard]
878. 第 N 个神奇数字 [Hard]
1201. 丑数 III [Medium]

# 668. 乘法表中第 K 小的数
class Solution:
    def findKthNumber(self, m: int, n: int, k: int) -> int:
        
        def check(x):
            cnt=0
            for i in range(1,m+1):
                cnt+=min(x//i,n)
            return cnt>=k
                
        l,r=1,m*n
        ans=1
        while l<=r:
            mid=(l+r)//2
            if check(mid):
                r=mid-1
                ans=mid
            else:
                l=mid+1
        return ans

可以看到,求第K小,就是在check(x)函数中,满足当前x的数量>=k就返回True。

未完成(因为这类题目很多用堆会更简便,所以后面没有多刷):
793. 阶乘函数后 K 个零 [Hard]
373. 查找和最小的 K 对数字 [Medium]
1439. 有序矩阵中的第 k 个最小数组和 [Hard]
786. 第 K 个最小的质数分数 [Medium]
3116. 单面值组合的第 K 小金额 [Hard]
3134. 找出唯一性数组的中位数 [Hard]
2040. 两个有序数组的第 K 小乘积 [Hard]
2386. 找出数组的第 K 大和 [Hard]
1508. 子数组和排序后的区间和 [Medium]
3520. 逆序对计数的最小阈值 [Medium]
1918. 第 K 小的子数组和 [Medium]

下面两个部分,灵神是单独拎出来的,个人觉得和求最小和求最大本质上没什么区别,所以没有刷,后面有时间再刷:

4) 最小化最大值

本质是二分答案求最小。二分的 mid 表示上界。

410. 分割数组的最大值 [Hard]
2064. 分配给商店的最多商品的最小值 [Medium]
1760. 袋子里最少数目的球 [Medium]
1631. 最小体力消耗路径 [Medium]
2439. 最小化数组中的最大值 [Medium]
2560. 打家劫舍 IV [Medium]
778. 水位上升的泳池中游泳 [Hard]
2616. 最小化数对的最大差值 [Medium]
3419. 图的最大边权的最小值 [Medium]
2513. 最小化两个数组中的最大值 [Medium]
3399. 字符相同的最短子字符串 II [Hard]
LCP 12. 小张刷题计划 [Medium]
774. 最小化去加油站的最大距离 [Hard]

5) 最大化最小值

本质是二分答案求最大。二分的 mid 表示下界。

3281. 范围内整数的最大得分 [Medium]
2517. 礼盒的最大甜蜜度 [Medium]
1552. 两球之间的磁力 [Medium]
2812. 找出最安全路径 [Medium]
2528. 最大化城市的最小电量 [Hard]
3449. 最大化游戏分数的最小值 [Hard]
3464. 正方形上的点之间的最大距离 [Hard]
1102. 得分最高的路径 [Medium]
1231. 分享巧克力 [Hard]

三、山脉数组

山脉数组,顾名思义,就是说数组中至少存在一个值,其值严格大于左右相邻值的元素。要求去寻找这个峰值。

162. 寻找峰值 [Medium]
1901. 寻找峰值 II [Medium]
852. 山脉数组的峰顶索引 [Medium]
1095. 山脉数组中查找目标值 [Hard]

# 162. 寻找峰值
class Solution:
    def findPeakElement(self, nums: List[int]) -> int:
        
        # 因为左右边界都有可能是山峰,所以左闭右闭
        l,r=0,len(nums)-1
        while l<r:
            mid=(l+r)//2
            # 往高处走,总能找到山峰
            if nums[mid]<nums[mid+1]:
                l=mid+1
            else:
                r=mid
        return l

注意,
1.为什么while的条件是l<r,不是l<=r?

  • l<r,表明l==r时触发结束条件,不用执行while内逻辑。我们知道,当l==r时,说明已经从左右两边逼近到山峰了,没有必要再去执行while内逻辑了,可以结束循环了。如果l<=r,那么就会死循环了。

2.山脉数组题型,总是相邻元素相比较nums[mid]<nums[mid+1]

3.为什么是l=mid+1r=mid

  • 我们还是考虑只剩两个元素的情况:mid总是指向前一个数。前一个数小于后一个数,那么向后移动,即l=mid+1;否则,向前移动,即r=mid。其他写法可能会导致死循环。

四、旋转数组

旋转数组是指一个已经正序的数组,从最后一个元素开始,依次挪到数组的最前面,一共挪k次。要求找到旋转之后的数组中的最小值。

旋转数组跟山脉数组解法相似,区别在于旋转数组是一直拿中间值跟右端点值比较。

153. 寻找旋转排序数组中的最小值 [Medium]
154. 寻找旋转排序数组中的最小值 II [Hard]
33. 搜索旋转排序数组 [Medium]
81. 搜索旋转排序数组 II [Medium]

# 153. 寻找旋转排序数组中的最小值
class Solution:
    def findMin(self, nums: List[int]) -> int:
        l,r=0,len(nums)-1
        while l<r:
            mid=(l+r)//2
            if nums[mid]<nums[r]:
                r=mid
            else:
                l=mid+1
        return nums[l]    

旋转数组其实就是由两部分正序的数组拼成,且前半部分数组的最小值大于后半部分数组的最大值。利用这一点,通过不断地比较中间值和右端点值,判断中间值是在前半部分还是后半部分。如果中间值小于右端点值,说明在后半部分,那么右边界往左移;否则,说明在前半部分,那么左边界往右移。

同样地,我们再来分析一下,
1.为什么while条件是l<r?不是l<=r?

  • 和山脉数组一样,当l==r时,我们已经找到了最小值,可以退出while循环了,没必要在进while循环执行一遍逻辑;

2.为什么是r=midl=mid+1?不是r=mid-1,不是l=mid

  • 同样地,我们只需要考虑只剩两个元素的情况。mid总是指向前面一个元素。如果最小值是前面一个元素,那么r=mid,此时l=r且都指向最小值,触发退出while循环条件。如果最小值是后面一个元素,那么l=mid+1,此时l=r且都指向最小值,退出循环。如果l=mid,那么就会死循环,无法退出while循环。

五、Hot:

4. 寻找两个正序数组的中位数 [Hard]
为什么把这题单独拎出来呢?嘿嘿,因为这题的方法确实不好归纳到上面四种题型中去。另外就是这题是Hot100,是面试中的常客,所以需要反复练习掌握。
具体题解可以参考:https://leetcode.cn/problems/median-of-two-sorted-arrays/solutions/3660794/deepseekti-jie-by-elk-r-xscq/

# 4. 寻找两个正序数组的中位数
class Solution:
    def findMedianSortedArrays(self, nums1: List[int], nums2: List[int]) -> float:

        if len(nums1)>len(nums2):
            nums1,nums2=nums2,nums1
            
        m,n=len(nums1),len(nums2)
        l,r,half=0,m,(m+n+1)//2
        
        while l<=r:
            i=(l+r)//2
            j=half-i
            
            # j=half-i
            #  =(m+n+1)//2-i
            #  >=(m+n+1)//2-m
            #  >=(n+1)//2-m//2
            #  >=0 (n>=m)
            # 所以不用判断j是否大于0
            if i<m and nums1[i]<nums2[j-1]:
                l=i+1
            elif i>0 and nums1[i-1]>nums2[j]:
                r=i-1
            else:
                if i==0:
                    max_left=nums2[j-1]
                elif j==0:
                    max_left=nums1[i-1]
                else:
                    max_left=max(nums1[i-1],nums2[j-1])
                    
                if (m+n)%2:
                    return max_left
                    
                if i==m:
                    min_right=nums2[j]
                elif j==n:
                    min_right=nums1[i]
                else:
                    min_right=min(nums1[i],nums2[j])
                    
                return (max_left+min_right)/2
         
        

六、其他:

69. x 的平方根 [Simple]
74. 搜索二维矩阵 [Medium]
240. 搜索二维矩阵 II [Medium]
2476. 二叉搜索树最近节点查询 [Medium]
278. 第一个错误的版本 [Simple]
374. 猜数字大小 [Simple]
222. 完全二叉树的节点个数 [Simple]

未完成
1539. 第 k 个缺失的正整数 [Simple]
540. 有序数组中的单一元素 [Medium]
1064. 不动点 [Simple]
702. 搜索长度未知的有序数组 [Medium]
2936. 包含相等值数字块的数量 [Medium]
1060. 有序数组中的缺失元素 [Medium]
1198. 找出所有行中最小公共元素 [Medium]
1428. 至少有一个 1 的最左端列 [Medium]
1533. 找到最大整数的索引 [Medium]
2387. 行排序矩阵的中位数 [Medium]
302. 包含全部黑色像素的最小矩形 [Hard]

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2396974.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【算法】分支限界

一、基本思想 &#xff08;分支限界&#xff0c; 分枝限界&#xff0c; 分支界限 文献不同说法但都是一样的&#xff09; 分支限界法类似于回溯法&#xff0c;也是一种在问题的解空间树上搜索问题解的算法。 但一般情况下&#xff0c;分支限界法与回溯法的求解目标不同。回溯…

数据库管理与高可用-MySQL全量,增量备份与恢复

目录 #1.1MySQL数据库备份概述 1.1.1数据备份的重要性 1.1.2数据库备份类型 1.1.3常见的备份方法 #2.1数据库完全备份操作 2.1.1物理冷备份与恢复 2.1.2mysqldump备份与恢复 2.1.3MySQL增量备份与恢复 #3.1制定企业备份策略的思路 #4.1扩展&#xff1a;MySQL的GTID 4.1.1My…

从gitee仓库中恢复IDEA项目某一版本

神奇的功能&#xff01;&#xff01;&#xff01;代码改乱了&#xff0c;但是还有救&#xff01; 打开终端&#xff0c;输入git log 复制想要恢复版本的提交哈希值&#xff0c;打开终端输入git reset --hard <哈希值> &#xff0c;就能修复到那时的提交版本了

用dayjs解析时间戳,我被提了bug

引言 前几天开发中突然接到测试提的一个 Bug&#xff0c;说我的时间组件显示异常。 我很诧异&#xff0c;这里初始化数据是后端返回的&#xff0c;我什么也没改&#xff0c;这bug提给我干啥。我去问后端&#xff1a;“这数据是不是有问题&#xff1f;”。后端答&#xff1a;“…

类和对象:实现日期类

目录 概述 一.实现日期类的基本框架 二.实现比较的运算符重载 1.>的运算符重载 2.的运算符重载 3.其余的比较运算符重载 三.加减天数的运算符重载 1.,的运算符重载 2.-&#xff0c;-的运算符重载 3.对1和2的小优化 四.两个日期类相减的重载 1.&#xff0c;--的重…

基于springboot的运动员健康管理系统

博主介绍&#xff1a;java高级开发&#xff0c;从事互联网行业六年&#xff0c;熟悉各种主流语言&#xff0c;精通java、python、php、爬虫、web开发&#xff0c;已经做了六年的毕业设计程序开发&#xff0c;开发过上千套毕业设计程序&#xff0c;没有什么华丽的语言&#xff0…

华为云Flexus+DeepSeek征文 | 初探华为云ModelArts Studio:部署DeepSeek-V3/R1商用服务的详细步骤

华为云FlexusDeepSeek征文 | 初探华为云ModelArts Studio&#xff1a;部署DeepSeek-V3/R1商用服务的详细步骤 前言一、华为云ModelArts Studio平台介绍1.1 ModelArts Studio介绍1.2 ModelArts Studio主要特点1.3 ModelArts Studio使用场景1.4 ModelArts Studio产品架构 二、访问…

下载即转化的商业密码:解析华为应用商店CPD广告的智能投放逻辑

在移动互联网流量红利见顶的背景下&#xff0c;华为应用市场凭借其终端生态优势正成为开发者获客的新蓝海。数据显示&#xff0c;2025年Q1华为应用商店全球分发量同比增长27%&#xff0c;其中CPD广告因其"下载才付费"的精准特性&#xff0c;已成为金融、游戏、工具类…

分布式锁和数据库锁完成接口幂等性

1、分布式锁 唯一主键与乐观锁的本质是使用了数据库的锁&#xff0c;但由于数据库锁的性能不太好&#xff0c;所以我们可使用Redis、Zookeeper等中间件来实现分布式锁的功能&#xff0c;以Redis为例实现幂等&#xff1a;当用户通过浏览器发起请求&#xff0c;服务端接收到请求…

浅谈JMeter之常见问题Address already in use: connect

浅谈JMeter之常见问题Address already in use: connect 在JMeter高并发测试中出现“address already in use”错误&#xff0c;主要源于Windows系统的TCP端口资源耗尽及连接配置问题&#xff0c;在执行JMeter中查看结果树 原因分析 GET请求默认采用短连接&#xff08;Conne…

【机器学习基础】机器学习入门核心算法:随机森林(Random Forest)

机器学习入门核心算法&#xff1a;随机森林&#xff08;Random Forest&#xff09; 1. 算法逻辑2. 算法原理与数学推导2.1 核心组件2.2 数学推导2.3 OOB&#xff08;Out-of-Bag&#xff09;误差 3. 模型评估评估指标特征重要性可视化 4. 应用案例4.1 医疗诊断4.2 金融风控4.3 遥…

【深度学习】12. VIT与GPT 模型与语言生成:从 GPT-1 到 GPT4

VIT与GPT 模型与语言生成&#xff1a;从 GPT-1 到 GPT4 本教程将介绍 GPT 系列模型的发展历程、结构原理、训练方式以及人类反馈强化学习&#xff08;RLHF&#xff09;对生成对齐的改进。内容涵盖 GPT-1、GPT-2、GPT-3、GPT-3.5&#xff08;InstructGPT&#xff09;、ChatGPT …

常规算法学习

算法 1. 排序算法1. 归并排序1.1 普通归并排序1.2 优化后的归并排序&#xff08;TimSort&#xff09; 2. 插入排序2.1 直接插入排序2.2 二分插入排序2.3 成对插入排序 3. 快速排序3.1 单轴快速排序3.2 双轴快排 4. 计数排序 2. 树1. 红黑树&#xff08;Red Black Tree&#xff…

Google 发布的全新导航库:Jetpack Navigation 3

前言 多年来&#xff0c;Jetpack Navigation 库一直是开发者的重要工具&#xff0c;但随着 Android 用户界面领域的发展&#xff0c;特别是大屏设备的出现和 Jetpack Compose 的兴起&#xff0c;Navigation 的功能也需要与时俱进。 今年的 Google I/O 上重点介绍了 Jetpack Na…

Arbitrum Stylus 合约实战 :Rust 实现 ERC20

在《Arbitrum Stylus 深入解析与 Rust 合约部署实战》篇中&#xff0c;我们深入探讨了 Arbitrum Stylus 的核心技术架构&#xff0c;包括其 MultiVM 机制、Rust 合约开发环境搭建&#xff0c;以及通过 cargo stylus 实现简单计数器合约的部署与测试。Stylus 作为 Arbitrum Nitr…

内存管理--《Hello C++ Wrold!》(8)--(C/C++)--深入剖析new和delete的使用和底层实现

文章目录 前言C/C内存分布new和deletenew和delete的底层定位new表达式 内存泄漏作业部分 前言 在C/C编程中&#xff0c;内存管理是理解程序运行机制的核心基础&#xff0c;也是开发高效、稳定程序的关键。无论是局部变量的存储、动态内存的分配&#xff0c;还是对象生命周期的…

Java进阶---JVM

JVM概述 JVM作用&#xff1a; 负责将字节码翻译为机器码&#xff0c;管理运行时内存 JVM整体组成部分&#xff1a; 类加载系统(ClasLoader)&#xff1a;负责将硬盘上的字节码文件加载到内存中 运行时数据区(RuntimeData Area)&#xff1a;负责存储运行时各种数据 执行引擎(Ex…

C++ 检查一条线是否与圆接触或相交(Check if a line touches or intersects a circle)

给定一个圆的圆心坐标、半径 > 1 的圆心坐标以及一条直线的方程。任务是检查给定的直线是否与圆相交。有三种可能性&#xff1a; 1、线与圆相交。 2、线与圆相切。 3、线在圆外。 注意&#xff1a;直线的一般方程是 a*x b*y c 0&#xff0c;因此输入中只给出常数 a、b、…

23. Merge k Sorted Lists

目录 题目描述 方法一、k-1次两两合并 方法二、分治法合并 方法三、使用优先队列 题目描述 23. Merge k Sorted Lists 方法一、k-1次两两合并 选第一个链表作为结果链表&#xff0c;每次将后面未合并的链表合并到结果链表中&#xff0c;经过k-1次合并&#xff0c;即可得到…

Unity + HybirdCLR热更新 入门篇

官方文档 HybridCLR | HybridCLRhttps://hybridclr.doc.code-philosophy.com/docs/intro 什么是HybirdCLR? HybridCLR&#xff08;原名 huatuo&#xff09;是一个专为 Unity 项目设计的C#热更新解决方案&#xff0c;它通过扩展 IL2CPP 运行时&#xff0c;使其支持动态加载和…