代码随想录算法训练营 Day1 | 704二分查找、24 移除元素

二分查找

二分查找其实是一个搜索算法,而且在704 中考察的是有序的无重复元素的数组。二分就是利用数组的有序来减少复杂度,相比完全遍历更加快。

二分查找的关键在于确定搜索的区间。在每轮循环中,我们如何更改区间,缩小查找的范围。

对于常见的二分,有两种写法,一种是区间左闭右开,另一种是左闭右闭。其实两者是一样的,主要看你搜索的区间的定义。

左闭右开

首先是左闭右开。我们搜索的区间是从[left, right) 并不包括right, 也就是说明在每次改变区间时候,right是取不到的。因此,while 循环中是left<right 这样区间才合理比如[0, 1) [1, 2),如果left = right,此时遍历的区间为[0, 0) 这是一个不合理的区间。第二个关键点,right初始化和right的变化。right 应该等于middle-1还是right=middle。还是明确,我们搜索的区间是[left, right) right边界我们是不会搜索到的,当nums[mid] > target,搜索区间应该变为[left, mid)  因为mid此时已经大于 target,mid就不应该在下一轮搜索的区间内, 但是middle-1在。因此right应该等于mid,此时搜索区间在[left, mid) 包含mid-1但是不包含mid.

def binary_search(nums: List[int], target: int):
    left, right = 0, len(nums) # right是取不到的
    while left < right:
        mid = (left + right) // 2
        if (nums[mid]> target):
            right = mid
        elif (nums[mid] < target):
            left = mid + 1
        else:
            return mid
    return -1 

左闭右闭

同样的,我们搜索的区间是从[left, right] 包括right, 也就是说明在每次改变区间时候,right是能够取到的。因此,while 循环中是left<=right 这样区间才合理比如[0, 1] [1, 2],如果left = right,此时遍历的区间为[0, 0]这仍然是一个合理的区间。第二个关键点,right初始化和right的变化。right 应该等于middle-1还是right=middle。还是明确,我们搜索的区间是[left, right] right边界我们是会搜索到的,当nums[mid] > target,搜索区间应该变为[left, mid] 因为mid此时已经大于 target,mid就不应该在下一轮搜索的区间内, 但是middle-1在。因此right应该等于mid-1,此时搜索区间在[left, right] 包含mid-1但是不包含mid.

def binary_search(nums: List[int], target: int):
    # 左闭右闭
    left, right = 0, len(nums)-1
    while left <= right:
        mid = (left + right)//2
        if (nums[mid]) > target:
            right = mid - 1
        elif (nums[mid] < target:
            left = mid + 1
        else:
            return mid
    return -1
    

移除元素

双向指针

移除这个题的解决思路可能一开始想不到用快慢指针,可能会想到用双指针,一个在最左边,一个在最右边(这是我做了二分后自然而然的一个思路),left 和right都在移动,直到相遇后退出循环。

那么这样做的话,就会有如下几种情况

1. left == val and right != val 那么可以直接赋值(或者两两交换) left +1 right - 1

2. left != val and right == val 那么 left+1  right-1

3. left !=val and right != val 那么left+1 right不动

4. left == val and right == val 那么 right -1 left 不动

循环条件要是[left, right] 因此可以取等

     def removeElement(self, nums: List[int], val: int) -> int:
        left, right = 0, len(nums)-1
        while left <= right:
            if nums[left] == val and nums[right] != val:
                nums[left] = nums[right]
                left += 1
                right -= 1
            elif nums[left] == val and nums[right] == val:
                right -= 1
            elif nums[left] != val and nums[right] != val:
                left += 1
            else:
                left += 1
                right -= 1
        return left

快慢指针

这里是参考的代码随想录的解析。两个指针都是从0开始,一个slow,一个fast,fast去遍历整个数组,slow用来储存非val的值。那么,我们想知道快和慢该如何移动呢?

首先我们确定循环的终止条件,那就是fast将数组遍历结束了,那就是fast < len(nums),

第二个,如何移动这个指正,快和慢的理解。快是指的是,fast一直在移动,那么slow什么时候移动? 当nums[fast] != val的,我开始移动,将nums[slow]=nums[fast],我直接赋值,保存nums[fast]访问到的不等于val的值。

def removeElement(nums: List[int], val:int):
    slow, fast = 0, 0
    while fast < len(nums):
        if nums[fast] != val:
            nums[slow] = nums[fast]
            slow += 1
        fast += 1
    return slow

暴力法

暴力法其实就是思路就是 如果找到val 那么对应的所有元素向前移动一位.

在nums[left] == val的时候,left-1的目的是移动到前面的值也有可能是val,如果不减去,后面又回+1直接跳过去

def removeElement(nums:List[int], val: int):
    left, right = 0, len(nums)
    while left < right:
        if nums[left] == val:
            for j in range(left+1, len(nums):
                nums[j-1] = nums[j]
            
            right -= 1
            left -= 1
        left += 1
        

气候风险指数是基于历史气候资料和未来气候预测结果,通过判断极端天气气候事件致灾阈值、结合社会经济数据及实际灾害损失分析,采用科学的方法对单一或综合气候灾害风险进行的定量化评价。一、中国各省市气候风险数据的介绍中国各省市气候风险数据主要包括极端低温、极端高温、极端降雨及极端干旱日数的相关数据,可为研究者进行气候风险评估、应对气候变化策略的制定及区域发展提供数据支持。数据年份:1993-2023年数据样本:31个省份,共962个省级样本;227个地级市,共6950个地级市样本二、数据指标指标定义数据类型LTD(极端低温日数)一年内气温低于某一极限值的天数数值HTD(极端高温日数)一年内气温高于某一极限值的天数数值ERD(极端降雨日数)一年内降雨量超过某一极限值的天数数值EDD(极端干旱日数)一年内降水量低于某一阈值的天数数值三、测算方式该气候风险指数的测算过程主要包括以下几个步骤:1. 对于缺失数据较多的样本进行剔除。2. 计算1973年11日至1992年12月31日间各项指标的历史分布。3. 计算1993至2023年间每个站点的极端天气事件类型。4. 计算区域层面上的年度极端天气天数。5. 综合各项指标计算最终的气候风险指数(CPRI)。四、数据来源该分享数据来自中国气候变化蓝皮书,原始气象数据来自NOAA(美国国家海洋和大气管理局)五、数据概览下图展示了中国气候风险指数的概览,包含了各省市在1993至2023年间的极端气候事件数据。通过这些数据,可以深入了解不同区域面临的气候风险程度,并为地方政府和相关机构制定应对策略提供参考。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值