代码随想录Day02:977.有序数组的平方 ,209.长度最小的子数组 ,59.螺旋矩阵II

这篇具有很好参考价值的文章主要介绍了代码随想录Day02:977.有序数组的平方 ,209.长度最小的子数组 ,59.螺旋矩阵II。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

Day02:977.有序数组的平方 ,209.长度最小的子数组 ,59.螺旋矩阵II

977.有序数组的平方

题目建议】: 本题关键在于理解双指针思想

【随想录文章讲解】

【卡哥视频讲解】

方法一:暴力排序法

**思路:**先对数组中每个数进行平方运算,然后再排序

class Solution {
public:
    vector<int> sortedSquares(vector<int>& A) {  
        for (int i = 0; i < A.size(); i++) {		//先计算出平方后的数组
            A[i] *= A[i];
        }
        sort(A.begin(), A.end()); // 快速排序  
        return A;
    }
};
  • 时间复杂度是 O(n + nlogn) 其中包括计算平方数组的O(n)和快速排序的O(nlogn),总体上是O(nlogn)
  • 空间复杂度:O(logn)。除了存储答案的数组以外,需要 O(logn) 的栈空间进行排序。
方法二:双指针法

思路:原始数组是有序的数组,那么平方后数组中最大的值在两端(不是在最左面就是最右面),这种情形考虑双指针法,i指向起始位置,j指向终止位置。

定义一个新数组result,和A数组一样的大小,让k指向result数组终止位置。让大的数逐渐进入result的队尾。

class Solution {
public:
    vector<int> sortedSquares(vector<int>& A) {
        int k = A.size()-1;						//这里定义k,后面让k指向result的尾部
        vector<int> result(A.size(),0);			//新知识:定义一个数组写法
        for(int i=0,j=A.size()-1;i<=j;){		// 循环终止条件,这里一定注意边界问题<=不然会出现漏掉元素的问题
            if(A[i]*A[i]<A[j]*A[j]){			//比较头部数据大还是尾部数据大
                result[k--]=A[j]*A[j];			//尾部数据大,进入result尾部
                j--;						
            }
            else{
                result[k--]=A[i]*A[i];			//头部数据大,进入result尾部
                i++;
            }

        }
               return result;					//输出这个数组
    }
};

  • 时间复杂度为O(n)
  • 空间复杂度:O(1)
209.长度最小的子数组

题目建议: 本题关键在于理解滑动窗口,这个滑动窗口看文字讲解 还挺难理解的,建议先看视频讲解。 拓展题目二刷做。

【题目链接】

【随想录文章讲解】

【卡哥视频讲解】

相关题目推荐

  • 904.水果成篮

  • 76.最小覆盖子串

方法一:暴力解法

**思路:**暴力解法当然是 两个for循环,然后不断的寻找符合条件的子序列,时间复杂度很明显是O(n^2)。

#include <iostream>         // 包含头文件。
#include<vector>
using namespace std;        // 指定缺省的命名空间。

int minSubArrayLen(int s, vector<int>& nums) {
    int result = INT32_MAX; // 最终的结果
    int sum = 0; // 子序列的数值之和
    int subLength = 0; // 子序列的长度
    for (int i = 0; i < nums.size(); i++) { // 设置子序列起点为i
        sum = 0;
        for (int j = i; j < nums.size(); j++) { // 设置子序列终止位置为j
            sum += nums[j];
            if (sum >= s) { // 一旦发现子序列和超过了s,更新result
                subLength = j - i + 1; // 取子序列的长度
                result = result < subLength ? result : subLength;
                break; // 因为我们是找符合条件最短的子序列,所以一旦符合条件就break
            }
        }
    }
    // 如果result没有被赋值的话,就返回0,说明没有符合条件的子序列
    return result == INT32_MAX ? 0 : result;
}

    int main() {
        vector<int> v{ 2,3,1,2,4,3 };
        cout << minSubArrayLen(7, v);

}
  • 时间复杂度:O(n^2)
  • 空间复杂度:O(1)
方法二:滑动窗口(双指针的思路)

思路不断的调节子序列的起始位置和终止位置,从而得出我们要想的结果

class Solution {
public:
    int minSubArrayLen(int s, vector<int>& nums) {
        int result = INT32_MAX;//获取有符号 int 对象的最大值  保证result会更新
        int sum = 0; // 滑动窗口数值之和
        int i = 0; // 滑动窗口起始位置
        int subLength = 0; // 滑动窗口的长度
        for (int j = 0; j < nums.size(); j++) {
            sum += nums[j];
            // 注意这里使用while,每次更新 i(起始位置),并不断比较子序列是否符合条件
            while (sum >= s) {
                subLength = (j - i + 1); // 取子序列的长度
                result = result < subLength ? result : subLength;
                sum -= nums[i++]; // 这里体现出滑动窗口的精髓之处,不断变更i(子序列的起始位置)
            }
        }
        // 如果result没有被赋值的话,就返回0,说明没有符合条件的子序列
        return result == INT32_MAX ? 0 : result;
    }
};

  • 时间复杂度:O(n)
  • 空间复杂度:O(1)
59.螺旋矩阵II

题目建议: 本题关键还是在转圈的逻辑,在二分搜索中提到的区间定义。本题并不涉及到什么算法,就是模拟过程,但却十分考察对代码的掌控能力。

【 题目链接 】 【 随想录文章讲解 】 【 卡哥视频讲解 】

思路:关键点是拐角上的点,求解本题依然是要坚持循环不变量原则,本题的方法是左闭右开。

class Solution {
public:
    vector<vector<int>> generateMatrix(int n) {
        vector<vector<int>> res(n, vector<int>(n, 0)); // 使用vector定义一个二维数组
        int startx = 0, starty = 0; // 定义每循环一个圈的起始位置
        int loop = n / 2; // 每个圈循环几次,例如n为奇数3,那么loop = 1 只是循环一圈,矩阵中间的值需要单独处理
        int mid = n / 2; // 矩阵中间的位置,例如:n为3, 中间的位置就是(1,1),n为5,中间位置为(2, 2)
        int count = 1; // 用来给矩阵中每一个空格赋值
        int offset = 1; // 需要控制每一条边遍历的长度,每次循环右边界收缩一位
        int i,j;
        while (loop --) {
            i = startx;
            j = starty;

            // 下面开始的四个for就是模拟转了一圈
            // 模拟填充上行从左到右(左闭右开)
            for (j = starty; j < n - offset; j++) {
                res[startx][j] = count++;
            }
            // 模拟填充右列从上到下(左闭右开)
            for (i = startx; i < n - offset; i++) {
                res[i][j] = count++;
            }
            // 模拟填充下行从右到左(左闭右开)
            for (; j > starty; j--) {
                res[i][j] = count++;
            }
            // 模拟填充左列从下到上(左闭右开)
            for (; i > startx; i--) {
                res[i][j] = count++;
            }

            // 第二圈开始的时候,起始位置要各自加1, 例如:第一圈起始位置是(0, 0),第二圈起始位置是(1, 1)
            startx++;
            starty++;

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

        // 如果n为奇数的话,需要单独给矩阵最中间的位置赋值
        if (n % 2) {
            res[mid][mid] = count;
        }
        return res;
    }
};

数组总结篇

二分法

数组:每次遇到二分法,都是一看就会,一写就废

这道题目呢,考察数组的基本操作,思路很简单,但是通过率在简单题里并不高,不要轻敌。

可以使用暴力解法,通过这道题目,如果追求更优的算法,建议试一试用二分法,来解决这道题目

  • 暴力解法时间复杂度:O(n)
  • 二分法时间复杂度:O(logn)

在这道题目中我们讲到了循环不变量原则,只有在循环中坚持对区间的定义,才能清楚的把握循环中的各种细节。

二分法是算法面试中的常考题,建议通过这道题目,锻炼自己手撕二分的能力

双指针法
  • 数组:就移除个元素很难么?

双指针法(快慢指针法):通过一个快指针和慢指针在一个for循环下完成两个for循环的工作。

  • 暴力解法时间复杂度:O(n^2)
  • 双指针时间复杂度:O(n)

这道题目迷惑了不少同学,纠结于数组中的元素为什么不能删除,主要是因为以下两点:

  • 数组在内存中是连续的地址空间,不能释放单一元素,如果要释放,就是全释放(程序运行结束,回收内存栈空间)。
  • C++中vector和array的区别一定要弄清楚,vector的底层实现是array,封装后使用更友好。

双指针法(快慢指针法)在数组和链表的操作中是非常常见的,很多考察数组和链表操作的面试题,都使用双指针法。

滑动窗口
  • 数组:滑动窗口拯救了你

本题介绍了数组操作中的另一个重要思想:滑动窗口。

  • 暴力解法时间复杂度:O(n^2)
  • 滑动窗口时间复杂度:O(n)

本题中,主要要理解滑动窗口如何移动 窗口起始位置,达到动态更新窗口大小的,从而得出长度最小的符合条件的长度。

滑动窗口的精妙之处在于根据当前子序列和大小的情况,不断调节子序列的起始位置。从而将O(n^2)的暴力解法降为O(n)。

如果没有接触过这一类的方法,很难想到类似的解题思路,滑动窗口方法还是很巧妙的。

模拟行为
  • 数组:这个循环可以转懵很多人!

模拟类的题目在数组中很常见,不涉及到什么算法,就是单纯的模拟,十分考察大家对代码的掌控能力。

在这道题目中,我们再一次介绍到了循环不变量原则,其实这也是写程序中的重要原则。

相信大家有遇到过这种情况: 感觉题目的边界调节超多,一波接着一波的判断,找边界,拆了东墙补西墙,好不容易运行通过了,代码写的十分冗余,毫无章法,其实真正解决题目的代码都是简洁的,或者有原则性的,大家可以在这道题目中体会到这一点。文章来源地址https://www.toymoban.com/news/detail-426688.html

到了这里,关于代码随想录Day02:977.有序数组的平方 ,209.长度最小的子数组 ,59.螺旋矩阵II的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【C++代码】有序数组的平方,长度最小的子数组,螺旋矩阵 II--代码随想录

    题目:有序数组的平方 给你一个按 非递减顺序 排序的整数数组 nums ,返回 每个数字的平方 组成的新数组,要求也按 非递减顺序 排序。 题解 数组其实是有序的, 只不过负数平方之后可能成为最大数了。那么数组平方的最大值就在数组的两端, 不是最左边就是最右边,不

    2024年02月11日
    浏览(44)
  • Day02 977.有序数组的平方 209.长度最小的子数组 59.螺旋矩阵II

    https://leetcode.cn/problems/squares-of-a-sorted-array/ 时间复杂度O(n) https://leetcode.cn/problems/minimum-size-subarray-sum/ 时间复杂度:O(n) 看每一个元素被操作的次数,每个元素在滑动窗后进来操作一次,出去操作一次,每个元素都是被操作两次,所以时间复杂度是 2 × n 也就是O(n)。 空间复杂度

    2023年04月18日
    浏览(38)
  • day2-数组part02| 977.有序数组的平方、 209.长度最小的子数组、 59.螺旋矩阵II

    数组平方后的最大值只可能在数组两端,不可能在中间 设置双指针,比较两个指针所指值的大小,记录较大值,接着向中间移动这个指针 结束条件:左右指针相背 暴力一直不过,明天再补一下 不断的调节子序列的起始位置和终止位置,从而得出我们要想的结果。 思路 子数

    2024年02月02日
    浏览(32)
  • 代码随想录day02

    ● 力扣题目链接 ● 给你一个按 非递减顺序 排序的整数数组 nums,返回 每个数字的平方 组成的新数组,要求也按 非递减顺序 排序。 思路 ● 暴力排序,时间复杂度O(n + nlogn) ● 使用双指针,时间复杂度O(n) 代码 ● 力扣题目链接 ● 给定一个含有 n 个正整数的数组和一个正整

    2024年02月13日
    浏览(47)
  • 【Day45】代码随想录之动态规划part7—爬楼梯(进阶)、零钱兑换、完全平方数

    今天又是补打卡的一天,开冲!!! 今日任务: 70.爬楼梯(进阶) 322.零钱兑换 279.完全平方数 这道题之前做过一次,但是可以采用完全背包的问题来分析一遍。 卡玛网题目:【57.爬楼梯】 这个题目其实是更难了一点,因为前面的题目都是每次要不爬1阶楼梯,要不爬2阶楼

    2024年03月25日
    浏览(52)
  • 代码随想录Day4 | 链表02-leetcode24、19、面试题02.07、142

    题目链接:两两交换链表中的节点 思路: 双指针p1、p2,分别指向每次需要交换的节点。交换过程为p2的next指向p1,p1的next指向p2的next, 还需要注意将p1de前一个指针指向交换后的p2以确保不断链 。 1. 空链 or 只有头结点? - 直接返回head,无需做任何修改 2. 交换需要记录前驱

    2024年02月12日
    浏览(39)
  • 代码随想录Day1 | 数组01- leetcode 704、27

    题目链接:二分查找 关键问题:         - 边界(left、right)、当前查找值(middle)                 - target大于当前查找值 -- 当前查找区域的右边,更改区间left                 - target小于当前查找值 -- 当前查找区域的左边,更改区间right                 - middle的计

    2024年02月16日
    浏览(43)
  • Day 2 数组:977.有序数组的平方 209.长度最小的子数组 59.螺旋矩阵Ⅱ

    977.有序数组的平方 题目链接 💡思路 暴力解法 将数组内每个数平方每个数平方之后,按升序排序 代码如下: 时间复杂度: O (   n l o g n ) O( nlogn) O (   n l o g n ) 空间复杂度: O ( 1 ) O(1) O ( 1 ) 时间复杂度具体分析: for循环: O(n) 快速排序 : O(nlogn) 因此时间复杂度是 O (  

    2024年02月10日
    浏览(49)
  • 算法训练 Day 2 | 数组:977.有序数组的平方,209.长度最小的子数组,59.螺旋矩阵II

    977. 有序数组的平方 第一想法:暴力破解 看完题解想法:朝着双指针方向想 遇到困难: 用双指针的话,一开始想到两边指针往中间靠,逐个将最大值赋给结果数组。和题解不同的是,循环条件我写了  while (left != right) {...} ,相比于题解的  while (left = right) {...} ,我需要在后

    2023年04月12日
    浏览(41)
  • 代码随想录day6|哈希表理论基础、有效的字母异位词、两个数组的交集、快乐数、两数之和

    当需要判断一个元素是否在一个集合中,哈希表的时间复杂度只有O(1)。 哈希表有一个映射的操作,当映射的元素在同一个索引下标的位置,就会引发 哈希碰撞 。 哈希碰撞的两种解决方法:拉链法 线性探测法   同时,哈希表还有常见的三种数据结构:分别是数组、集合s

    2024年02月06日
    浏览(46)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包