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

Leet code: 704.二分查找

题目链接:力扣

学习文章:代码随想录 

初印象:拿到题目,能够比较容易理解二分法的思想,取中值选前后段。但是在实际代码实现的过程中,边界问题特别容易出现混乱,尤其是出现数组越界的情况,而且往往一头雾水。

学习提升:看完代码随想录中的讲解后,根据闭区间和半闭半开区间,始终保持target在目标区间内就可以清楚地知道边界的取值。

# 闭区间 [left, right]
class Solution(object):
    def search(self, nums, target):
        """
        :type nums: List[int]
        :type target: int
        :rtype: int
        """
        left = 0
        right = len(nums) - 1
        while left <= right:
            middle = int((left + right) / 2)
            if nums[middle] > target:
                right = middle - 1
            elif nums[middle] < target:
                left = middle + 1
            else:
                return middle

        return -1

# 半闭半开区间 [left, right)
class Solution(object):
    def search(self, nums, target):
        """
        :type nums: List[int]
        :type target: int
        :rtype: int
        """
        left = 0
        right = len(nums)
        while left < right:
            middle = int((left + right) / 2)
            if nums[middle] > target:
                right = middle
            elif nums[middle] < target:
                left = middle + 1
            else:
                return middle

        return -1

 对比分析两种区间的解法,可以发现区别主要在于right是闭区间还是开区间,同样两种方式的代码的主要差别也在right,需要修改right的初始值,以及迭代更新的表达式。但无论那种方式,只要牢牢抓住"target要在区间内"就OK。

复杂度分析:时间复杂度 O(log(n)); 空间复杂度 O(1)


Leet code: 27. 移除元素

题目链接:力扣

学习文章:代码随想录

初印象:该题主要考察数组的删除,由于数组在内存中地址连续,如果需要在某个位置删除或者增加一个元素,除了修改插入的位置,该位置之后的元素都需要前移或者后移,非常麻烦。看到题目首先的想法是分两步:查找 + 删除。先要找到需要删除的元素的位置,然后再进行删除操作。

学习提升:有了初步的思路之后,并且参考代码随想录的想法,对暴力破解进行实现,补充了双指针法。暴力破解:每找到一个val,就对整个数组进行一次删除操作,需要两个循环。而双指针法仅仅用了两个"指针"就将算法的降为一个循环就可以解决,着实巧妙。

# 暴力破解方法
class Solution(object):
    def removeElement(self, nums, val):
        """
        :type nums: List[int]
        :type val: int
        :rtype: int
        """
        i,l = 0, len(nums)
        while i < l:
            if nums[i] == val:
                for j in range(i+1,l):
                    nums[j - 1] = nums[j]
                l = l - 1
                i = i - 1
            i = i + 1
        return l

# 快慢指针方法
class Solution(object):
    def removeElement(self, nums, val):
        """
        :type nums: List[int]
        :type val: int
        :rtype: int
        """
        slowindex = 0
        fastindex = 0
        while fastindex < len(nums):
            
            if nums[fastindex] == val:
                fastindex += 1
            else:
                nums[slowindex] = nums[fastindex]
                fastindex +=1
                slowindex +=1
            
        return slowindex

对比两种方法,第一种方法遇到了数组越界的问题,边界的取值还花了一些时间,反观第二种方法,只要明确了快指针用来指向新元素,慢指针用来指向结果数组的最后一个元素,在遇到val时,跳过即可,思路清晰明了。

复杂度分析: 时间复杂度 O(n^2) (暴力破解) O(n) (双指针法); 空间复杂度 O(1)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值