学习记录 | day1 数组基础

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


记录算法学习的第一天


一、LeetCode 704-二分查找

给定一个 n 个元素有序的(升序)整型数组 nums 和一个目标值 target  ,写一个函数搜索 nums 中的 target,如果目标值存在返回下标,否则返回 -1

示例 1:

输入: nums= [-1,0,3,5,9,12], target= 9输出: 4
解释: 9 出现在nums中并且下标为 4
题目链接:https://leetcode.cn/problems/squares-of-a-sorted-array/

二分法概念:首先我们要先明白二分法有几部分构成 它由三部分 左区间 右区间 middle构成 我们就是(左区间+右区间)/2然后得出middle 再和target相对比看看target是在middle左边还是右边 在左边就是right=middle-1 在右边我们就left=middle+1 最后求到最后left=right时就是我们target的下标 

解题思路:我们常见思路就是两种方法 一种是左闭右闭 一种是左闭右开

1.左闭右闭写法[left,right]

class Solution:
    def search(self, nums: List[int], target: int) -> int:
        left = 0
        right = 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

2.左闭右开写法[left,right)

class Solution:
    def search(self, nums: List[int], target: int) -> int:
        left = 0
        right = len(nums)

        while left < right:
            middle = left + (right - left) // 2 #这里不要(left+****)//2会超时

            if nums[middle] > target:
                right = middle
            elif nums[middle] < target:
                left = middle + 1
            else:
                return middle
        return -1

3.难点

       1.right的确定       

  •        左闭右闭区间[left,right]

                nums= [-1,0,3,5,9,12]它从头到尾遍历6次所以我们可以确定left=0,right=5 也就是        right=len(nums)-1

  •   right在左闭右闭中可以为middle-1 假设target为3那么就是说可以右区间移动就可以说    middle-1变成[-1,0,3] 3是可以取得到的所以left的+1 right-1都无所谓了
  •  ``左闭右开区间[left,right)

                nums= [-1,0,3,5,9,12]它从头到尾遍历6次所以我们可以确定left=0,但是这里的          right我们取不到所以我们的right要为6也就是right=len(nums)

  •     right在左闭右开的区间中如果说target就正好紧接着middle的左边那就middle-1就可能取不      到了 所以就需要right=middle

  2.middle的确定 

  • mid = (right - left) // 2 这种写法运用在这里根本就是错误的。因为right - left 仅仅代表两者之间相差几个数的距离,再除以2只是说从左到右的一半距离,和下标就没有关系了。

  • mid = (right + left) // 2这种写法会发生上溢问题。int 占用 4 字节,32 比特,数据范围为:-2147483648 ~ 2147483647 [-2^31 ~ 2^31-1]

    那么对于两个都接近 2147483647的数字而言,它们相加的结果将会溢出,变成负数。所以,为了避免溢出情况的发生,我们不采用这种写法。

  • mid = left + (right - left) // 2 从左指针到右指针的一半距离 + 左指针的下标 才是符合题的下标位置。

总结

        在写二分法时经常要注意区间的问题 左闭右闭 左闭右开的情况然后就是确定right怎么写左闭右开就是middle 左闭右闭middle-1 然后就是middle的确定 


二、LeetCode 27-移除元素

题目描述:给你一个数组 nums 和一个值 val,你需要 原地 移除所有数值等于 val 的元素,并返回移除后数组的新长度。

题目链接:leetcode.cn/problems/re…icon-default.png?t=N7T8https://link.juejin.cn?target=https%3A%2F%2Fleetcode.cn%2Fproblems%2Fremove-element%2F

题目描述

给你一个数组 nums 和一个值 val,你需要 原地 移除所有数值等于 val 的元素,并返回移除后数组的新长度。不要使用额外的数组空间,你必须仅使用 O(1) 额外空间并 原地 修改输入数组

元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素。

  • 暴力解法

#暴力解法
class Solution:
    def removeElement(self, nums: List[int], val: int) -> int:
        i=0 
        l=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
  • 双指针解法

class Solution:
    def removeElement(self, nums: List[int], val: int) -> int:
        slow=0 #慢指针
        fast=0 #快指针
        for fast in range(fast,len(nums)):
            if nums[fast]!=val:
                nums[slow]=nums[fast]
                slow += 1
            fast +=1
        return slow
  • 解题思路

        定义两个指针 一个快指针来遍历原来数组寻找需要的元素 一个慢指针在后面跟着更新的数组 这样就可以用一个for循环完成 时间复杂度为O(n)

  • 难点

        经常容易第一反应是暴力解法 双指针解法会是更优解

  •     总结

        双指针解法经常用在数组和链表当中要多多练习


总结

        前路漫漫 脚踏实地的走吧

  • 17
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值