Leetcode刷题第二天 | Leetcode 977,209,59

Leetcode 977 有序数组的平法,Leetcode 27 长度最小的子数组,Leetcode 螺旋矩阵II

Leetcode 977

给你一个按 非递减顺序 排序的整数数组 nums,返回每个数字的平方 组成的新数组,要求也按 非递减顺序 排序。
示例1:
输入:nums = [-4,-1,0,3,10]
输出:[0,1,9,16,100]
解释:平方后,数组变为 [16,1,0,9,100]
排序后,数组变为 [0,1,9,16,100]
示例2:
输入:nums = [-7,-3,2,3,11]
输出:[4,9,9,49,121]
提示:

  1. 1 <= nums.length <= 1 0 4 10^4 104
  2. - 1 0 4 10^4 104 <= nums[i] <= 1 0 4 10^4 104
  3. nums已按非递减顺序排序

实现方法: 利用双指针解决问题,头指针指向开始位置,尾指针指向结尾位置;两个指针分别从左向右运动和从从右向左运动,直到两个指针相遇,即为结束条件。
代码实现

class Solution:
    def sortedSquares(self, nums: List[int]) -> List[int]:
        l, r, i = 0, len(nums)-1, len(nums)-1	# l 左指针;r 右指针;i 存放结果的指针
        res = [float('inf')] * len(nums) # 需要提前定义列表,存放结果
        while l <= r:
            if nums[l] ** 2 < nums[r] ** 2: # 左右边界进行对比,找出最大值
                res[i] = nums[r] ** 2
                r -= 1 # 右指针往左移动
            else:
                res[i] = nums[l] ** 2
                l += 1 # 左指针往右移动
            i -= 1 # 存放结果的指针需要往前平移一位
        return res

**注意:**为什么while l < = r l <= r l<=r而不是while l < r l < r l<r?
如果 l < r l < r l<r,那就意味着 l l l r r r相等的位置即循环结束的位置,最终不会加入到结果列表中。
复杂度:
时间复杂度: O ( n ) O(n) O(n)

Leetcode 209

给定一个含有 n 个正整数的数组和一个正整数 target 。
找出该数组中满足其和 ≥ target 的长度最小的连续子数组 [numsl, numsl+1, …, numsr-1, numsr] ,并返回其长度。如果不存在符合条件的子数组,返回 0 。
示例 1:
输入:target = 7, nums = [2,3,1,2,4,3]
输出:2
解释:子数组 [4,3] 是该条件下的长度最小的子数组。
示例 2:
输入:target = 4, nums = [1,4,4]
输出:1
示例 3:
输入:target = 11, nums = [1,1,1,1,1,1,1,1]
输出:0
提示:

  1. 1 <= target <= 1 0 9 10^9 109
  2. 1 <= nums.length <= 1 0 5 10^5 105
  3. 1 <= nums[i] <= 1 0 5 10^5 105

实现方法: 暴力实现 和滑动窗口法
代码实现:

class Solution:
    def minSubArrayLen(self, s: int, nums: List[int]) -> int:
        l = len(nums)
        left = 0
        right = 0
        min_len = float('inf')
        cur_sum = 0 #当前的累加值
        
        while right < l:
            cur_sum += nums[right]
            
            while cur_sum >= s: # 当前累加值大于目标值
                min_len = min(min_len, right - left + 1)
                cur_sum -= nums[left]
                left += 1
            
            right += 1
        
        return min_len if min_len != float('inf') else 0

复杂度:

  1. 时间复杂度: O ( n ) O(n) O(n)
  2. 空间复杂度: O ( 1 ) O(1) O(1)

注意:
为什么时间复杂度 是 O ( n ) O(n) O(n)?在外层循环中,所有数组元素被遍历一次 ,而在内层循环中,每个元素也是被遍历一次,因此时间复杂度没有达到 O ( n 2 ) O(n^2) O(n2)
例如:与冒泡排序不同,冒泡排序最多需要 n − 1 n-1 n1次操作可以将所有元素排序,每一次操作都需要比较两个元素的大小,也就是总的比较和交换次数达到 O ( n 2 ) O(n^2) O(n2)的级别。

Leetcode 59

给你一个正整数 n ,生成一个包含 1 到 n 2 n^2 n2 所有元素,且元素按顺时针顺序螺旋排列的 n x n 正方形矩阵 matrix 。
示例 1:
输入:n = 3
输出:[[1,2,3],[8,9,4],[7,6,5]]
示例 2:
输入:n = 1
输出:[[1]]
提示:
1 <= n <= 20

实现方式:
逐个边遍历,填充数据。

代码实现

class Solution:
    def generateMatrix(self, n: int) -> List[List[int]]:
        nums = [[0] * n for _ in range(n)]
        startx, starty = 0, 0               # 起始点
        loop, mid = n // 2, n // 2          # 迭代次数、n为奇数时,矩阵的中心点
        count = 1                           # 计数

        for offset in range(1, loop + 1) :      # 每循环一层偏移量加1,偏移量从1开始
            for i in range(starty, n - offset) :    # 从左至右,左闭右开
                nums[startx][i] = count
                count += 1
            for i in range(startx, n - offset) :    # 从上至下
                nums[i][n - offset] = count
                count += 1
            for i in range(n - offset, starty, -1) : # 从右至左
                nums[n - offset][i] = count
                count += 1
            for i in range(n - offset, startx, -1) : # 从下至上
                nums[i][starty] = count
                count += 1                
            startx += 1         # 更新起始点
            starty += 1

        if n % 2 != 0 :			# n为奇数时,填充中心点
            nums[mid][mid] = count 
        return nums

复杂度:

  1. 时间复杂度: O ( n 2 ) O(n^2) O(n2)

数组题目总结

二分法

使用条件:有序数组,查找操作

双指针法(快慢指针法)

使用条件:当一个指针无法解题,或者需要使用一次循环完成两次循环里才能解决的问题时,需要考虑使用双指针。

滑动窗口

使用条件:差找子序列,可以考虑滑动窗口。

模拟行为

使用条件:这种题目主要考察逻辑思维。通常需要遵循循环不变量原则。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值