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

一、有序数组的平方

1、思路:双指针

2、重点注意事项:

  1. 最大的数一定是出现在数组的两端
  2. i<=j 原因是 :当i和j同时指向同一个数组需要满足想等条件否则会跳出循环
  3. i++和j-- 都是有一定条件的所有不放在for循环条件括号内(取决于谁的元素大)
  4. 在 C++ 中,A.size() 函数返回的是容器 A(在这个上下文中,A 是一个 std::vector 类型的向量)中元素的数量。因此,A.size() - 1 计算的是 A 中最后一个元素的索引。在 C++(以及许多其他编程语言)中,索引是从 0 开始的,所以最后一个元素的索引是元素总数减一。
  5. 注意result[k–],使用 result[k–] 的原因是为了在填充结果数组 result 时,从数组的末尾开始向前填充。这里的 k-- 是一个后缀递减运算符,它的行为是先返回 k 的当前值,然后将 k 的值减一
class Solution {
public:
    vector<int> sortedSquares(vector<int>& nums) 
    {
        int k = nums.size()-1;
        vector<int> result(nums.size(),0);
        for(int i = 0 , j = nums.size() - 1; i <= j;)
        {
            if(nums[i]* nums[i] < nums[j]* nums[j])
            {
                result[k--]=nums[j]* nums[j];
                j--;
            }else
            {
                result[k--]=nums[i]* nums[i];
                i++;
            }
        }
        return result;
    }
};

二、长度最小的子数组

1、思路:滑动窗口

class Solution {
public:
    int minSubArrayLen(int target, vector<int>& nums) 
    {
        int result = INT32_MAX;
        int sum = 0;
        int i = 0;
        int sublength = 0;
        for(int j = 0; j < nums.size() ; j++)
        {
            sum += nums[j];
            while(sum >= target)
            {
                sublength = (j - i + 1);
                result = result < sublength ? result : sublength;
                sum -= nums[i++];
            }
        }
        return result == INT32_MAX ? 0 : result;
    }
};

注意点:

  1. j < nums.size() - 1。这意味着循环不会遍历到数组的最后一个元素。如果最后一个元素是解决方案的一部分,这个循环就会错过它。应该将条件改为 j < nums.size()。
  2. sum -= nums[i++]; 滑动的应该是i

三、螺旋矩阵

1、知识点:

循环不变量原则(Loop Invariant Principle)是计算机科学中,特别是在算法分析和程序验证中一个非常重要的概念。它用于描述在循环执行过程中始终保持为真(即不变)的某个条件或属性。这个原则主要用于证明算法的正确性,尤其是在使用归纳法证明时。

定义:循环不变量是一个在循环开始前成立,且在每次循环迭代中保持为真,直到循环结束的属性或条件。这个原则要求:

  1. 初始化:在循环开始前,循环不变量必须为真。
  2. 保持:在每次循环迭代中,循环不变量必须保持为真。这通常意味着循环体内的操作不会违反循环不变量的条件。
  3. 终止:当循环结束时(无论是正常结束还是由于某种条件提前退出),循环不变量仍然为真,并且这个条件可以用来证明算法的正确性或目的已经达到。

注意事项:每画一条边都要坚持一致的左闭右开,或者左开右闭的原则,这样这一圈才能按照统一的规则画下来。

class Solution {
public:
    vector<vector<int>> generateMatrix(int n) {
        vector<vector<int>> res(n, vector<int>(n, 0)); 
        // 这行代码创建了一个名为 res 的二维向量(或称为向量的向量)
        //它包含 n 个行向量,每个行向量也包含 n 个整数元素,且所有这些整数元素都被初始化为 0 
        //vector<vector<int>>:这是一个模板类型,表示一个二维向量,其中每个元素都是一个整数向量
        int i , j;
        int loop = n / 2;
        int mid = n / 2;
        int startx = 0, starty = 0;
        int count = 1;
        int offset = 1;
        while (loop--)
        {
            i = startx;
            j = starty;
            for(j; j < n-offset; j++)
            {
                res[i][j] = count++;
            }
            for(i; i < n-offset; i++)
            {
                res[i][j] = count++;
            }
            for(;j > startx; j--)
            {
                res[i][j] = count++;
            }
            for(; i > starty; i--)
            {
                res[i][j] = count++;
            }
            startx++;
            starty++;
            offset += 1;
        }
        if (n % 2)
        {
            res[mid][mid] = count;
        }
        return res;
    }

};

vector<vector>:这是一个模板类型,表示一个二维向量,其中每个元素都是一个整数向量(vector)。简单来说,它是一个二维数组的动态版本,其中你可以根据需要动态地增加或减少行和列的数量(虽然在这个特定的初始化语句中,大小是固定的)。
res:这是这个二维向量的变量名。
(n, vector(n, 0)):这是 res 的构造函数参数,用于初始化 res。
n:这是第一个参数,指定了 res 应该有多少行(即外层向量的元素数量)。
vector(n, 0):这是第二个参数,它是一个临时创建的整数向量(vector),它本身也被初始化为 n 个元素,每个元素都被初始化为 0。这个临时向量作为第一个参数的“值”被传递给 res 的构造函数,意味着 res 的每一行都将被初始化为这样一个包含 n 个 0 的向量。

  • 9
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 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题,题目要求在给定的数组中找到长度最小数组,使得数组的和大于等于给定的目标值。这里可以使用滑动窗口的方法来解决问题。使用两个指针来表示滑动窗口的左边界和右边界,通过移动指针来调整滑动窗口的大小,使得滑动窗口中的元素的和满足题目要求。具体实现的代码如下: ```python def minSubArrayLen(self, target: int, nums: List[int]) -> int: left = 0 right = 0 ans = float('inf') total = 0 while right < len(nums): total += nums[right] while total >= target: ans = min(ans, right - left + 1) total -= nums[left] left += 1 right += 1 return ans if ans != float('inf') else 0 ``` 以上就是第二十二天的算法训练营的内容。通过这些题目的练习,可以提升对双指针和滑动窗口等算法的理解和应用能力。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值