代码随想录day1

一、二分法查找:

题目:

1.问题剖析:一组数字升序、无重复,才能用二分查找

2.解法

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

3.题目要点与收货:

  • 确立区间开闭[L,R] or [L,R)
  • 根据区间开闭确定while迭代条件(不冲突原则,若都为闭区间,可以取等于号;一开一闭,取不等号)
  • 根据区间开闭确定right迭代公式(闭区间的一端,不能为原值,需要移动,nums[middle]><target已经成功判断middle不在后续查找的区间内,而while的条件是可以取等于号的)
  • python的注解,变量注解(var : 类型),函数注解(->类型)

二、移除元素

题目:

1.问题剖析:数组不能删除元素,只能覆盖元素!

2.解法:

  • 暴力移动:两个循环,O(n^2)
(版本二)暴力法
class Solution:
    def removeElement(self, nums: List[int], val: int) -> 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 -= 1
                i -= 1
            i += 1
        return l
  • 双指针法:

        构建两个指针,一个fast,一个slow。fast用来遍历元素,比较是否与val相等,slow用来覆写,将不等于val的元素存储,并覆盖原来的元素。slow指向不重复元素后面一个位置(下一个不重复元素需要插入的位置),fast指针一直遍历数组。

class Solution(object):
    def removeElement(self, nums, val):
        """
        :type nums: List[int]
        :type val: int
        :rtype: int
        """
        fast=0
        slow=0
        while fast<=len(nums)-1:
            if nums[fast]!=val:
                nums[slow]=nums[fast]
                slow+=1
            fast+=1
        return slow
  • 双向指针法:

构建两个指针,一个left,一个right。在 while left <= right的条件下(因为都是闭区间,所以用<=),将两个指针向中间移动,当left遇到val时,将右指针元素赋值给左指针元素,两个指针再向中间移动一步,继续循环。

class Solution(object):
    def removeElement(self, nums, val):
        """
        :type nums: List[int]
        :type val: int
        :rtype: int
        """
        left,right=0,len(nums)-1
        while left <= right:
            while left<=right and nums[left]!=val:
                left+=1
            while left<=right and nums[right]==val:
                right-=1
            if left<right:
                nums[left]=nums[right]
                left+=1
                right-=1
        return left

3.题目要点与收货:

索引 i 的两个意义:

  • 索引位置元素相对于0位置的 i 个偏移量
  • 索引位置元素之前,已经存储了 i 个元素

常用操作:   

前提条件:设置指针为0

执行阶段:
while 循环条件
    1.判断条件
        2.赋值操作
        3.指针移动,大小+1

在跳出while循环后,指针数字的大小,就代表了循环中的操作执行总次数。在本题中,代表了在指针位置之前已经存储了i(i=指针的数字大小)个元素。所以直接返回指针即可,代表了移除target后元素的个数

                        

  • 5
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值