代码随想录算法训练营第一天| 704. 二分查找、27. 移除元素

文章总结:

文章链接:https://programmercarl.com/%E6%95%B0%E7%BB%84%E7%90%86%E8%AE%BA%E5%9F%BA%E7%A1%80.html

对于数组,其特点在于:

  • 下标从0开始

  • 内存空间的地址是连续的

在C++中对于int型整数(16进制)的存储如图:

注:在16进制中c代表12(8 + 4 = c)

题目总结:

704: 二分查找:

第一想法:

比较两个边界大小,当nums[l] < target时,l += 1, 当nums[r] > target时,r -= 1

class Solution(object):
    def search(self, nums, target):
        """
        :type nums: List[int]
        :type target: int
        :rtype: int
        """
        l,r = 0, len(nums) - 1

        while l < r:
            if nums[l] < target:
                l += 1
            elif nums[r] > target:
                r -= 1
        if target == nums[l]:
            return l
        else:
            return -1

缺点:速度较慢

二分法:

主要思路:找区间中间值,比较中间值与target的大小,再对于边界进行改变

难点:边界的控制(区间是否闭合,修改边界时是否-1)

闭区间:[left, right] (baseline)
  • left = right 时是有意义的 → while left <= right:

  • 当left = right有意义时,面临的问题在于陷入死循环,所以我们要避开死循环 → 在修改边界时 l = middle + 1, r = middle - 1

class Solution(object):
    def search(self, nums, target):
        """
        :type nums: List[int]
        :type target: int
        :rtype: int
        """
        l,r = 0, len(nums) - 1

        while l <= r:
            M = (l + r) // 2
            if nums[M] < target:
                l = M + 1
            elif nums[M] > target:
                r = M - 1
            else:
                return M
        
        return -1
左闭右开区间:[left, right)
  • left = right没有意义 → while left < right:

  • left = right 没有意义就意味着我们在对于右边界修改时没有必要-1,因为nums[right]没有意义

class Solution(object):
    def search(self, nums, target):
        """
        :type nums: List[int]
        :type target: int
        :rtype: int
        """
        l,r = 0, len(nums)

        while l < r:
            M = (l + r) // 2
            if nums[M] < target:
                l = M + 1
            elif nums[M] > target:
                r = M
            else:
                return M
        
        
        return -1

注:注意r同时也要换成len(nums)因为区间变为了左闭右开

27:移除元素:

没有第一想法

快慢指针:

对于数组中元素的移除需要将后面的元素都向前移动,所以为了减少时间复杂度,对于暴力解法中的for循环的叠加需要去除。

改用快慢指针:

当fast指针的数值与val相等时,需要将fast指针前移

实际上就是利用fast指针向后寻找不等于目标值的数,然后前移

所以slow向前移动的条件是找到了不等于目标值的数

两个指针的用途:

slow:确定需要前移的位置

fast:寻找不等于val的数值

class Solution(object):
    def removeElement(self, nums, val):
        """
        :type nums: List[int]
        :type val: int
        :rtype: int
        """
        

        slow = 0
        fast = 0
        size = len(nums)

        while fast < size:
            if nums[fast] != val:
                nums[slow] = nums[fast]
                slow += 1
            fast += 1

        return slow

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值