算法学习:数组(python)

1.二分查找

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

适用:顺序数组,无重复
解题:循环查找,每次循环范围缩小一半

方法一:[left,right]

1、循环条件是left<=right, 因为是[4,4]是存在的
2、if target < nums[middle]: right = middle - 1,nums[middle]肯定不是target,直接进入左边区间找就行了

from typing import List
nums = [-1,0,3,5,9,12,15]
prompt="Please input a nummber you want to searh:"
target = input(prompt)
target = int(target)
def binary_search(nums: List[int],target: int):
    left = 0
    right = len(nums)-1

    while left<=right:
        middle = (left + right)//2
        print("left:",left,"right",right,"middle:",middle)
        if target < nums[middle]:
            right = middle - 1
        elif target > nums[middle]:
            left = middle +1
        else:
            return middle
    return -1
print("result:",binary_search(nums,target))

运行结果:

Please input a nummber you want to searh:9
left: 0 right 6 middle: 3
left: 4 right 6 middle: 5
left: 4 right 4 middle: 4
result: 4

方法二:[left,right)

1、循环条件是left<right,因为[4,4)没有意义
2、if target < nums[middle]: right = middle,这里没有减一是因为让它去左闭右开的区间里寻找,而且并不会找nums[middle]

from typing import List
nums = [-1,0,3,5,9,12,15]
prompt="Please input a nummber you want to searh:"
target = input(prompt)
target = int(target)
def binary_search(nums: List[int],target: int):
    left = 0
    right = len(nums)-1

    while left < right:
        middle = (left + right)//2
        print("left:",left,"right",right,"middle:",middle)
        if target < nums[middle]:
            right = middle
        elif target > nums[middle]:
            left = middle +1
        else:
            return middle
    return -1
print("result:",binary_search(nums,target))

运行结果:

Please input a nummber you want to searh:9
left: 0 right 6 middle: 3
left: 4 right 6 middle: 5
left: 4 right 5 middle: 4
result: 4

2.移除元素

27.给你一个数组 nums 和一个值 val,你需要 原地 移除所有数值等于 val 的元素,并返回移除后数组的新长度。
不要使用额外的数组空间,你必须仅使用 O(1) 额外空间并原地修改输入数组。
元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素。

方法一:相向双指针

时间复杂度O(n)
空间复杂度O(1)

from typing import List

nums = [3,2,2,3]

def removeElement(nums: List[int],val: int):
    if nums is None or len(nums)==0:
        return 0
    left = 0
    right = len(nums)-1
    while left < right :
        while left<right and nums[left] != val:
            left+=1		#找到前面等于val的数
        while left<right and nums[right]==val:
            right-=1	#找到后面不等于val的数
        nums[left],nums[right] = nums[right],nums[left]
        print(nums)
    if nums[left]==val:
        print(left)
        return left
    else:
        print(left+1)
        return left+1
removeElement(nums,3)

因为最后会在left=right时退出循环(并且多进行一次交换)如果此处的值为val,则最后一个数的下标是left-1,而返回的是数组长度,需要+1

[2, 2, 3, 3]
[2, 2, 3, 3]
2

方法二:快慢指针法

时间复杂度O(n)
空间复杂度O(1)

from typing import List

nums = [-1,0,3,3,9,3,15]

def removeElement(nums: List[int],val: int):
    slowIndex ,fastIndex = 0,0
    while fastIndex < len(nums):
        if nums[fastIndex] != val:
            if slowIndex != fastIndex: #加一个判断语句优化没必要的赋值
                nums[slowIndex] = nums[fastIndex]
                print(nums)
            slowIndex+=1
        fastIndex+=1
removeElement(nums,3)

运行结果:

[-1, 0, 9, 3, 9, 3, 15]
[-1, 0, 9, 15, 9, 3, 15]

3.有序数组的平方

977.给你一个按 非递减顺序 排序的整数数组 nums,返回 每个数字的平方 组成的新数组,要求也按 非递减顺序 排序。

示例 1: 输

from typing import List

nums = [-10,-6,-4,-1,0,3,10,11,15]

def sortedSquares(nums: List[int]):
    res=[]
    left,right = 0,len(nums)-1
    while left<=right :
        if nums[left]>0 :
            res.insert(0, nums[right] ** 2)
            right-=1
        elif -nums[left]<nums[right] :
            res.insert(0, nums[right] ** 2)
            right-=1
        else:
            res.insert(0, nums[left] ** 2)
            left+=1
        print(res)
    return res

sortedSquares(nums)

运行结果:

[225]
[121, 225]
[100, 121, 225]
[100, 100, 121, 225]
[36, 100, 100, 121, 225]
[16, 36, 100, 100, 121, 225]
[9, 16, 36, 100, 100, 121, 225]
[1, 9, 16, 36, 100, 100, 121, 225]
[0, 1, 9, 16, 36, 100, 100, 121, 225]

4.长度最小的子数组

209.给定一个含有 n 个正整数的数组和一个正整数 s ,找出该数组中满足其和 ≥ s 的长度最小的 连续 子数组,并返回其长度。如果不存在符合条件的子数组,返回 0。

滑动窗口解法

from typing import List

target = 4
nums = [1,4,4]

def minSubArrayLen(nums: List[int],target: int):
    result = float("inf")       #定义一个极大数
    sum = 0     #滑动窗口的总和
    subLength = 0       #滑动窗口的长度
    i = 0       #滑动窗口的起始位置
    j = 0       #滑动窗口的终止位置
    while j < len(nums):        #终止位置为j的最短窗口
        sum += nums[j]      #加入这个j的值
        while sum >= target :       #找到最短的窗口
            subLength = j - i +1
            if result > subLength:
                result = subLength
            sum = sum - nums[i]     #再删除第一个窗口值
            i+=1	#删除后起始位置移动
        j+=1

    if result > len(nums):
        return 0
    else:
        return result
        
print(minSubArrayLen(nums,target))

5.螺旋矩阵II

59.给定一个正整数 n,生成一个包含 1 到 n^2 所有元素,且元素按顺时针顺序螺旋排列的正方形矩阵。

def generateMatrix(n:int):
    nums = [[0] * n for _ in range(n)]
    startx,starty = 0,0
    loop = n//2
    count = 1
    for offset in range(1,loop+1):
        for j in range(starty,n-offset):
            nums[startx][j] = count
            count+=1
        for i in range(startx,n-offset):
            nums[i][n-offset] =count
            count+=1
        for j in range(n-offset,starty,-1):
            nums[n-offset][j] = count
            count+=1
        for i in range(n-offset,startx,-1):
            nums[i][starty] = count
            count+=1
        startx+=1
        starty+=1
    if n%2 == 1:
        nums[n//2][n//2] = count
    return nums

nums=generateMatrix(5)
for i in range(len(nums)):
    print(nums[i])

运行结果:

[1, 2, 3, 4, 5]
[16, 17, 18, 19, 6]
[15, 24, 25, 20, 7]
[14, 23, 22, 21, 8]
[13, 12, 11, 10, 9]

查找方向和查找控制范围

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值