代码随想录算法训练营第二天| LeetCode977.有序数组的平方,LeetCode209.长度最小子数组,LeetCode59.螺旋矩阵II

题目链接:977. 有序数组的平方 - 力扣(LeetCode)

文章讲解:代码随想录 (programmercarl.com)

视频讲解:双指针法经典题目 | LeetCode:977.有序数组的平方_哔哩哔哩_bilibili

思路:

双指针法

有序数组,平方后的最大值肯定由数组的头和尾产生。

关键点:双指针法的 i 和 j 分别指向什么。i 起始位置,j 终止位置。新数组填充,从终端开始,k取终止位置。

// C++代码

class Solution {
public:
    vector<int> sortedSquares(vector<int>& nums) {
        vector<int> results(nums.size(), 0);
        int i = 0;
        int j = nums.size() - 1;
        int k = nums.size() - 1;

        for (i; i <= j; ) {
            if (nums[i]*nums[i] < nums[j]*nums[j]) {
                results[k--] = nums[j]*nums[j];
                j--;
            }
            else {
                results[k--] = nums[i]*nums[i];
                i++;
            }
        }

        return results;
    }
};
# python代码

class Solution(object):
    def sortedSquares(self, nums):
        """
        :type nums: List[int]
        :rtype: List[int]
        """
        result = [0] * len(nums)
        i, j, k = 0, len(nums) - 1, len(nums) - 1

        while i <= j :
            if (nums[i]*nums[i] < nums[j]*nums[j]) :
                result[k] = nums[j]*nums[j]
                k -= 1
                j -= 1
            else :
                result[k] = nums[i]*nums[i]
                k -= 1
                i += 1
        
        return result

题目链接:209. 长度最小的子数组 - 力扣(LeetCode)

文章讲解:代码随想录 (programmercarl.com)

视频讲解:拿下滑动窗口! | LeetCode 209 长度最小的子数组_哔哩哔哩_bilibili

思路:

滑窗法(双指针法的一种)

所谓滑动窗口,就是不断的调节子序列的起始位置和终止位置

滑动窗口也可以理解为双指针法的一种,i 子序列起始位置,j 子序列终止位置

只用一个for循环,那么这个循环的索引,一定是表示 滑动窗口(子序列)的终止位置j

j 完成一个循环,在循环内比较 子序列的和 和 target 的大小,满足条件后,调节子序列长度

//C++代码

class Solution {
public:
    int minSubArrayLen(int target, vector<int>& nums) {
        int i = 0, j = 0;
        int res = INT32_MAX;
        int sub_len = 0;
        int sum = 0;

        for (j; j < nums.size(); j++) {
            sum += nums[j];

            while (sum >= target) {
                sub_len = j - i + 1;
                res = res < sub_len ? res : sub_len;

                sum -= nums[i];
                i++;
            }
        }

        return res != INT32_MAX ? res : 0l;
    }
};
#python代码

class Solution(object):
    def minSubArrayLen(self, target, nums):
        """
        :type target: int
        :type nums: List[int]
        :rtype: int
        """
        i = 0
        sum = 0
        res, sub_len = float('inf'), 0

        for j in range(0, len(nums)) :
            sum += nums[j]

            while sum >= target :
                sub_len = j - i + 1
                res = min(res, sub_len)

                sum -= nums[i]
                i += 1

        return res if res != float('inf') else 0

题目链接:59. 螺旋矩阵 II - 力扣(LeetCode)

文章讲解:代码随想录 (programmercarl.com)

视频讲解:一入循环深似海 | LeetCode:59.螺旋矩阵II_哔哩哔哩_bilibili

思路:

这道题难点在边界条件非常多

在一个循环中,如此多的边界条件,一定要设置好固定的规则来遍历,坚持循环不变量原则

模拟顺时针画矩阵的过程:

  • 填充上行从左到右
  • 填充右列从上到下
  • 填充下行从右到左
  • 填充左列从下到上

区间坚持左闭右开原则,如下图所示

循环的边界条件一定要构思好,给定 n ,若 n 为奇数,如左图所示,循环 n / 2 次即可,中心位置特殊处理;若 n 为偶数,如右图所示,循环 n / 2 次即可,无需特殊处理;然后就是每条边的 for 循环的边界条件,以上行边为例,从x = start_x 开始,到 x = n - 1 - offset 为止;

//C++代码

class Solution {
public:
    vector<vector<int>> generateMatrix(int n) {
        vector<vector<int>> result(n, vector<int>(n, 0));
        int loop = n / 2;  // 循环次数(每次循环处理四个边)
        vector<int> odd_center(2, n / 2);

        int start_x = 0, start_y = 0;
        int offset = 1;
        int cnt = 1;

        int x = 0, y = 0;
        while (loop--) {
            x = start_x;
            y = start_y;

            //上行边,从左到右,左闭右开
            for (x; x < n - offset; x++) {
                result[y][x] = cnt++;
            }
            //右列边,从上到下,左闭右开
            for (y; y < n - offset; y++) {
                result[y][x] = cnt++;  //上一个for结束,x = n - offset
            }
            //下行边,从右到左,左闭右开
            for (; x > start_x; x--) {
                result[y][x] = cnt++;
            }
            //左列边,从下到上,左闭右开
            for (; y > start_y; y--) {
                result[y][x] = cnt++;
            }

            //第二圈开始的时候,起始位置要各自加1
            start_x++;
            start_y++;

            // offset 控制每一圈里每一条边遍历的长度
            offset++;
        }

        if (n % 2 != 0) {
            result[odd_center[0]][odd_center[1]] = n*n;
        }

        return result;
    }
};
#python代码

class Solution(object):
    def generateMatrix(self, n):
        """
        :type n: int
        :rtype: List[List[int]]
        """
        res = [[0]*n for _ in range(n)]
        loop = n // 2
        start_x, start_y = 0, 0
        offset = 1
        cnt = 1

        while loop :
            for i in range(start_x, n - offset) :
                res[start_y][i] = cnt
                cnt += 1
            for i in range(start_y, n - offset) :
                res[i][n - offset] = cnt
                cnt += 1
            for i in range(n - offset, start_x, -1) :
                res[n - offset][i] = cnt
                cnt += 1
            for i in range(n - offset, start_y, -1) :
                res[i][start_x] = cnt
                cnt += 1
            
            start_x += 1
            start_y += 1
            offset += 1
            loop -= 1

        if n % 2 != 0 :
            res[n // 2][n // 2] = n*n

        return res

  • 4
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
第二十二天的算法训练主要涵盖了Leetcode题目中的三道题目,分别是Leetcode 28 "Find the Index of the First Occurrence in a String",Leetcode 977 "有序数组的平方",和Leetcode 209 "长度最小的子数组"。 首先是Leetcode 28题,题目要求在给定的字符串中找到第一个出现的字符的索引。思路是使用双指针来遍历字符串,一个指向字符串的开头,另一个指向字符串的结尾。通过比较两个指针所指向的字符是否相等来判断是否找到了第一个出现的字符。具体实现的代码如下: ```python def findIndex(self, s: str) -> int: left = 0 right = len(s) - 1 while left <= right: if s[left == s[right]: return left left += 1 right -= 1 return -1 ``` 接下来是Leetcode 977题,题目要求对给定的有序数组中的元素进行平方,并按照非递减的顺序返回结果。这里由于数组已经是有序的,所以可以使用双指针的方法来解决问题。一个指针指向数组的开头,另一个指针指向数组的末尾。通过比较两个指针所指向的元素的绝对值的大小来确定哪个元素的平方应该放在结果数组的末尾。具体实现的代码如下: ```python def sortedSquares(self, nums: List[int]) -> List[int]: left = 0 right = len(nums) - 1 ans = [] while left <= right: if abs(nums[left]) >= abs(nums[right]): ans.append(nums[left ** 2) left += 1 else: ans.append(nums[right ** 2) right -= 1 return ans[::-1] ``` 最后是Leetcode 209题,题目要求在给定的数组中找到长度最小的子数组
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值