「代码随想录」Python刷题笔记Day2-数组专题

977.有序数组的平方

leetcode-977

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

本题的目标就是学习双指针。本题真的太让人想return sorted(x*x for x in nums)了,没想到拆解开后,双指针的想法真的是十分巧妙。早上看完题目和提示用双指针后,设想了一下,左指针用来计算平方,右指针用来判断和替换,想着想着又变成暴力求解了?加上一个用来存放结果的指针就看起来正常多了。

class Solution:
    def sortedSquares(self, nums: List[int]) -> List[int]:
        left, right, k = 0, len(nums)-1, len(nums)-1
        ans = [0] * len(nums)
        while left <= right:
            if nums[left] * nums[left] > nums[right]*nums[right]:
                ans[k] = nums[left] * nums[left]
                left += 1
            elif nums[left] * nums[left] <= nums[right]*nums[right]:
                ans[k] = nums[right] * nums[right]
                right -= 1
            k -= 1
        return ans

看了答案后发现

  1. k -= 1可以放到if的外面;
  2. 等于的场景可以合并到小于的场景里面;
  3. 时间复杂度O(n)

参考资料:
977.有序数组的平方

209.长度最小的子数组

leetcode-977

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

本质上是两层for循环,用滑动窗口进行优化。滑动窗口本身也是一个双指针,用一个for循环做了两个for循环做的事。
自己先写了写,周末再来整理。

class Solution:
    def minSubArrayLen(self, target: int, nums: List[int]) -> int:
        left, right = 0, len(nums)-1
        cumsum = 0
        result = float('inf')
        for right in range(len(nums)):
            cumsum += nums[right]
            while cumsum >= target:
                sublen = right - left + 1
                result = min(result, sublen)
                # 收缩左指针
                cumsum = cumsum - nums[left]
                left += 1
        return 0 if result == inf else result

注:
时间复杂度是O(n),每个元素在滑动窗后进来操作一次,出去操作一次,每个元素都是被操作两次,所以时间复杂度是 2 × n 也就是O(n)。

参考资料:
209.长度最小的子数组
其他题目:
904.水果成篮
76.最小覆盖子串

59.螺旋矩阵II

leetcode-59

给定一个正整数 n,生成一个包含 1 到 n^2 所有元素,且元素按顺时针顺序螺旋排列的正方形矩阵。
示例:
输入: 3 输出: [ [ 1, 2, 3 ], [ 8, 9, 4 ], [ 7, 6, 5 ] ]
class Solution:
    def generateMatrix(self, n: int) -> List[List[int]]:
        matrix = [[0 for _ in range(n)] for _ in range(n)]
        upper_bound, lower_bound = 0, n - 1
        left_bound, right_bound = 0, n - 1
        num = 1
        
        while num <= n * n:
            if upper_bound <= lower_bound:
                # 在顶部从左向右遍历
                for j in range(left_bound, right_bound+1):
                    matrix[upper_bound][j] = num
                    num += 1
                # 上边界下移
                upper_bound += 1
            
            if left_bound <= right_bound:
                # 在右侧从上向下遍历
                for i in range(upper_bound, lower_bound+1):
                    matrix[i][right_bound] = num
                    num += 1
                # 右边界左移
                right_bound -= 1
        
            if upper_bound <= lower_bound:
                # 在底部从右向左遍历
                for j in range(right_bound, left_bound-1, -1):
                    matrix[lower_bound][j] = num
                    num += 1
                # 下边界上移
                lower_bound -= 1
            
            if left_bound <= right_bound:
                # 在左侧从下向上遍历
                for i in range(lower_bound, upper_bound-1, -1):
                    matrix[i][left_bound] = num
                    num += 1
                # 左边界右移
                left_bound += 1
        
        return matrix

考察二维码数组的遍历,已经被绕晕……

参考资料:
59.螺旋矩阵II

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值