算法训练记录day2

文章介绍了三道编程题目:1)如何保持有序性对数组进行平方操作,提出了冒泡排序和双指针两种解决方案;2)找到数组中最小子数组的长度,使用双指针滑动窗口方法;3)生成螺旋矩阵的算法,重点在于一圈一圈填充的逻辑处理。
摘要由CSDN通过智能技术生成

一、有序数组的平方

题目

思路

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

  • 思路

看到题目的第一想法是:先平方,再用冒泡排序。

  1. 如何给列表元素平方(或者其他操作)

nums = [-4,-1,0,3,10]
nums1 = [x**2 for x in nums]
  1. 冒泡排序 (升序)

从第一个元素开始,让其与右边相邻的元素比较大小,如果大于右边元素,则交换位置

while i <= n:
    for j in range(i+1,n):
        if nums1[j] < nums1[i]:
            nums1[j],nums1[i] = nums1[i],nums1[j]  # 交换位置
        else:
            continue
    i+=1 # 第一个下标的元素交换完了 就从下一个开始 继续交换
  1. 双指针思路

  • 在平方后的列表中比较大小,然后由后往前填入较大的值

利用双指针,一前一后比较数值大小(nums1),然后移动数值大的指针(i或者j),再将大的值填入初始列表(nums)的最后位置

利用k -=1 控制初始列表的指针移动

n = len(nums)-1
i = 0  #指针指向第一个元素  nums1
j = n  #指针指向最后一个元素 nums1
k = n  #指针指向最后一个元素  nums

while k >= 0: # nums中 k 的最后一个下标是 0 所以要取等号
    if nums1[j] > nums1[i]:  # 先比较
        nums[k] = nums1[j]   # 将大的数值填入nums 中的k下标位置
        j-=1  # 此条件 移动 j指针
    else:
        nums[k] = nums1[i]
        i+=1  # 此条件 移动 i指针
    k-=1 #每次比较完 移动 k指针

二、长度最小的子数组

题目209

思路

开始题目理解错了,子数组的意思是要其连续,即下标是连续的。

  • 双指针(滑动窗口)

即两个指针,前后组成一个子数字,通过指针的移动,使得窗口发生变化。

class Solution:
    def minSubArrayLen(self, target: int, nums: List[int]) -> int:
        i = 0     # 这个指针在后 
        n = len(nums)
        sum = 0   # 窗口内的元素之和  起始时,i=j=0 
        res = float("inf")  
        for j in range(n):   # 指针在前,负责往窗口里加入元素
            sum += nums[j]    # 指针往前走,把走过的元素相加
            while sum >= target:  # 当窗口元素之和大于target时,才开始循环
                res = min(j-i+1,res)  # 如果一直没有满足判定条件,那么res = 无穷大
     就没有符合条件的子数组
                sum -= nums[i] # 删除掉窗口的第一元素 , 然后进行判断,是否需要循环
                i+=1   #后指针往前走一步
        return 0 if res == float("inf") else res

三、 螺旋矩阵 II

题目

思路

  • 重点

需要一圈一圈的处理。从最外层到下一层。

如果圈数为偶数,则直接处理

如果为奇数,需要在最中心,赋值一个数。

  • 难点

  1. 如何一圈圈处理

一圈一共4个边,保证遍历每个边时,数目一样,避免有的节点被重复或者遗漏。

(一个矩形有4个角,即为4个节点)每一圈也是

从左往右,从上往下,从右往左,从下往上

需要设置起始点,x y = 0 这是为了处理下一圈 。 每一圈的起始节点都不一样

class Solution:
    def generateMatrix(self, n: int) -> List[List[int]]:
        matrix = [[0]*n for i in range(n)]  #  构造一个二维矩阵
        x = 0          # x ,y 对应 矩阵下标 i  j
        y = 0          # 设置起始节点
        count =1       # 计数 赋值
        loop =  n//2   # 计算圈数
        mid = n//2     # 确定 中间点的位置 
        for k in range(1,loop+1):        # 对圈子进行循环  第一圈、第二圈。。。
            for j in range(y,n-k):        # 从左往右 从起始点 到下一个节点 不包含这个节点
                matrix[x][j] = count       # x不变 y依次增加 
                count += 1                 # 赋值
            for i in range(x,n-k):         # 从上往下  
                matrix[i][n-k] = count      # y不变 x依次增加 
                count += 1
            for j in range(n-k,y,-1):       # 从右往左 需要逆序
                matrix[n-k][j] = count        # x不变 y依次减小
                count += 1
            for i in range(n-k,x,-1):         #从下往上  需要逆序
                matrix[i][y] = count            # y不变 x依次减小
                count += 1
            x += 1                               # 下一圈的起始点 需要往前一步
            y += 1                                # x,y 需要加1
        if n % 2 != 0 :            
            matrix[mid][mid] = count               # 奇数 给中间位置赋值
        return matrix

n 是矩阵的宽度,k是圈数。

每一圈中的每一条边,元素个数,正好是n-k (推理得到)

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值