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

news2024/11/22 20:57:00

题目:有序数组的平方

  • 给你一个按 非递减顺序 排序的整数数组 nums,返回 每个数字的平方 组成的新数组,要求也按 非递减顺序 排序。
题解
  • 数组其实是有序的, 只不过负数平方之后可能成为最大数了。那么数组平方的最大值就在数组的两端,不是最左边就是最右边,不可能是中间。可以使用两个指针分别指向位置 0 和 n−1,每次比较两个指针对应的数,选择较大的那个逆序放入答案并移动指针。时间复杂度:O(n),其中 n 是数组 nums 的长度。空间复杂度:O(1)。除了存储答案的数组以外,我们只需要维护常量空间。

  • 如果A[i] * A[i] < A[j] * A[j] 那么result[k--] = A[j] * A[j]; 。如果A[i] * A[i] >= A[j] * A[j] 那么result[k--] = A[i] * A[i];

  • class Solution {
    public:
        vector<int> sortedSquares(vector<int>& nums) {
            int left=0,right=nums.size()-1;
            int ptr_index = nums.size()-1;
            vector<int> res(ptr_index+1);
            while(left<=right){
                if(nums[left]*nums[left] < nums[right]*nums[right]){
                    res[ptr_index] = nums[right]*nums[right];
                    --right;
                }else{
                    res[ptr_index] = nums[left]*nums[left];
                    ++left;
                }
                --ptr_index;
            }
            return res;
        }
    };
    
  • 此时的时间复杂度为O(n),相对于暴力排序的解法O(n + nlog n)还是提升不少的。

题目:长度最小的子数组

  • 给定一个含有 n 个正整数的数组和一个正整数 target 。找出该数组中满足其和 ≥ target 的长度最小的 连续子数组 [numsl, numsl+1, ..., numsr-1, numsr] ,并返回其长度。如果不存在符合条件的子数组,返回 0
题解
  • 这道题目暴力解法当然是 两个for循环,然后不断的寻找符合条件的子序列,时间复杂度很明显是 O ( n 2 ) O(n^2) O(n2)。接下来就开始介绍数组操作中另一个重要的方法:滑动窗口。代码随想录 (programmercarl.com)

  • 所谓滑动窗口,就是不断的调节子序列的起始位置和终止位置,从而得出我们要想的结果。在暴力解法中,是一个for循环滑动窗口的起始位置,一个for循环为滑动窗口的终止位置,用两个for循环 完成了一个不断搜索区间的过程。 那么滑动窗口如何用一个for循环来完成这个操作呢?如果只用一个for循环来表示 滑动窗口的起始位置,那么如何遍历剩下的终止位置?

  • 只用一个for循环,那么这个循环的索引,一定是表示 滑动窗口的终止位置。

    • 在这里插入图片描述
  • 在本题中实现滑动窗口,主要确定如下三点:

    • 窗口内是什么?(窗口就是 满足其和 ≥ s 的长度最小的 连续 子数组)

    • 如何移动窗口的起始位置?(如果当前窗口的值大于s了,窗口就要向前移动了)

    • 如何移动窗口的结束位置?(窗口的结束位置就是遍历数组的指针,也就是for循环里的索引)

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

  • 不要以为for里放一个while就以为是 O ( n 2 ) O(n^2) O(n2) 啊, 主要是看每一个元素被操作的次数,每个元素在滑动窗后进来操作一次,出去操作一次,每个元素都是被操作两次,所以时间复杂度是 2 × n 也就是O(n)

  • class Solution {
    public:
        int minSubArrayLen(int target, vector<int>& nums) {
            int len_nums = nums.size();
            int sum = 0;
            int start_index = 0,sub_len=len_nums+3;
            for(int i = 0;i<len_nums;i++){
                sum += nums[i];
                while(sum>=target){
                    sub_len = min(sub_len,i-start_index+1);
                    sum -= nums[start_index];
                    start_index++;
                }
            }
            return sub_len>len_nums?0:sub_len;
        }
    };
    

题目:螺旋矩阵 II

  • 给你一个正整数 n ,生成一个包含 1n2 所有元素,且元素按顺时针顺序螺旋排列的 n x n 正方形矩阵 matrix
题解
  • 本题并不涉及到什么算法,就是模拟过程,但却十分考察对代码的掌控能力。模拟矩阵的生成。按照要求,初始位置设为矩阵的左上角,初始方向设为向右。若下一步的位置超出矩阵边界,或者是之前访问过的位置,则顺时针旋转,进入下一个方向。如此反复直至填入 n 2 n^2 n2 个元素。求解本题要坚持循环不变量原则。模拟顺时针画矩阵的过程:

    • 填充上行从左到右

    • 填充右列从上到下

    • 填充下行从右到左

    • 填充左列从下到上

  • 由外向内一圈一圈这么画下去。这里一圈下来,我们要画每四条边,这四条边怎么画,每画一条边都要坚持一致的左闭右开,或者左开右闭的原则,这样这一圈才能按照统一的规则画下来。

  • class Solution {
    public:
        vector<vector<int>> generateMatrix(int n) {
            vector<vector<int>> res(n,vector<int>(n,0));
            int startx=0,starty=0;
            int cirle = n/2;
            int offset=1;
            int count=1;
            int i,j;
            while(cirle--){
                i=startx;
                j=starty;
                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++;
                }
                startx++;
                starty++;
                offset++;
            }
            if(n%2){
                res[startx][starty]=count++;
            }
            return res;
        }
    };
    

C++ STL 四种智能指针

  • C++ 标准模板库 STL(Standard Template Library) 一共给我们提供了四种智能指针:auto_ptr、unique_ptr、shared_ptr 和 weak_ptr,其中 auto_ptr 是 C++98 提出的,C++11 已将其摒弃,并提出了 unique_ptr 替代 auto_ptr。虽然 auto_ptr 已被摒弃,但在实际项目中仍可使用,但建议使用更加安全的 unique_ptr。shared_ptr 和 weak_ptr 则是 C++11 从准标准库 Boost 中引入的两种智能指针。此外,Boost 库还提出了 boost::scoped_ptr、boost::scoped_array、boost::intrusive_ptr 等智能指针,虽然尚未得到 C++ 标准采纳,但是在开发实践中可以使用C++ STL 四种智能指针_c++智能指针_恋喵大鲤鱼的博客-CSDN博客。

  • C++ 智能指针底层是采用引用计数的方式实现的。智能指针在申请堆内存空间的同时,会为其配备一个整形值(初始值为 1),每当有新对象使用此堆内存时,该整形值 +1;反之,每当使用此堆内存的对象被释放时,该整形值减 1。当堆空间对应的整形值为 0 时,即表明不再有对象使用它,该堆空间就会被释放掉。

  • 每种智能指针都是以类模板的方式实现的,shared_ptr 也不例外。shared_ptr(其中 T 表示指针指向的具体数据类型)的定义位于<memory>头文件,并位于 std 命名空间中,因此在使用该类型指针时,程序中应包含如下 2 行代码:

    • #include <memory>
      using namespace std;
      
unique_ptr
  • 作为智能指针的一种,unique_ptr 指针自然也具备“在适当时机自动释放堆内存空间”的能力。和 shared_ptr 指针最大的不同之处在于,unique_ptr 指针指向的堆内存无法同其它 unique_ptr 共享,也就是说,每个 unique_ptr 指针都独自拥有对其所指堆内存空间的所有权。

  • 这也就意味着,每个 unique_ptr 指针指向的堆内存空间的引用计数,都只能为 1,一旦该 unique_ptr 指针放弃对所指堆内存空间的所有权,则该空间会被立即释放回收。

  • 创建空的 unique_ptr 指针

    • std::unique_ptr<int> p1();
      std::unique_ptr<int> p2(nullptr);
      
  • 构建 unique_ptr 智能指针并初始化确定数据

    • std::unique_ptr<int> p3(new int);
      
  • 基于 unique_ptr 类型指针不共享各自拥有的堆内存,因此 C++11 标准中的 unique_ptr 模板类没有提供拷贝构造函数,只提供了移动构造函数。例如:

    • std::unique_ptr<int> p4(new int);
      std::unique_ptr<int> p5(p4);//错误,堆内存不共享
      std::unique_ptr<int> p5(std::move(p4));//正确,调用移动构造 函 数 
      //值得一提的是,对于调用移动构造函数的 p4 和 p5 来说,
      //p5 将获取 p4 所指堆空间的所有权,而 p4 将变成空指针(nullptr)。
      
  • 默认情况下,unique_ptr 指针采用 std::default_delete 方法释放堆内存。也可自定义释放规则。和 shared_ptr 指针不同, unique_ptr 自定义释放规则只能采用函数对象的方式。

shared_ptr
  • 值得一提的是,和 unique_ptr、weak_ptr 不同之处在于,多个 shared_ptr 智能指针可以共同使用同一块堆内存。并且,由于该类型智能指针在实现上采用的是引用计数机制,即便有一个 shared_ptr 指针放弃了堆内存的“使用权”(引用计数减 1),也不会影响其他指向同一堆内存的 shared_ptr 指针(只有引用计数为 0 时,堆内存才会被自动释放)。

  • 构造 shared_ptr 类型的空智能指针

    • std::shared_ptr<int> p1; //不传入任何实
      std::shared_ptr<int> p2(nullptr); //传入空指针 nullptr
      
  • 构建 shared_ptr 智能指针并初始化确定数据

    • std::shared_ptr<int> p3(new int(10));
      std::shared_ptr<int> p3 = std::make_shared<int>(10);
      //调用拷贝构造函数
      std::shared_ptr<int> p4(p3);//或者 std::shared_ptr<int> p4 = p3;
       //调用移动构造函数
      std::shared_ptr<int> p5(std::move(p4)); //或者 
       std::shared_ptr<int> p5 = std::move(p4);
      
  • 如上所示,p3 和 p4 都是 shared_ptr 类型的智能指针,因此可以用 p3 来初始化 p4,由于 p3 是左值,因此会调用拷贝构造函数。需要注意的是,如果 p3 为空智能指针,则 p4 也为空智能指针,其引用计数初始值为 0;反之,则表明 p4 和 p3 指向同一块堆内存,同时该堆空间的引用计数会加 1。而对于 std::move(p4) 来说,该函数会强制将 p4 转换成对应的右值,因此初始化 p5 调用的是移动构造函数。另外和调用拷贝构造函数不同,用 std::move(p4) 初始化 p5,会使得 p5 拥有了 p4 的堆内存,而 p4 则变成了空智能指针。

  • 注意:一普通指针不能同时为多个 shared_ptr 对象赋值,否则会导致程序发生异常。例如:

    • int* ptr = new int;
      std::shared_ptr<int> p1(ptr);
      std::shared_ptr<int> p2(ptr);//错误
      
  • 初始化 shared_ptr 智能指针时,可自定义堆内存的释放规则,当堆内存的引用计数为 0 时,会优先调用自定义的释放规则。

    • //指定 default_delete 作为释放规则
      std::shared_ptr<int> p6(new int[10], std::default_delete<int[]>());
      //自定义释放规则
      void deleteInt(int*p) {
       delete []p;
      }
      //初始化智能指针,并自定义释放规则
      std::shared_ptr<int> p7(new int[10], deleteInt);
      

weak_ptr

  • C++11标准虽然将 weak_ptr 定位为智能指针的一种,但该类型指针通常不单独使用(没有实际用处),只能和 shared_ptr 类型指针搭配使用。甚至于,我们可以将 weak_ptr 类型指针视为 shared_ptr 指针的一种辅助工具,借助 weak_ptr 类型指针, 我们可以获取 shared_ptr 指针的一些状态信息,比如有多少指向相同的 shared_ptr 指针、shared_ptr 指针指向的堆内存是否已经被释放等等

  • 需要注意的是,当 weak_ptr 类型指针的指向和某一 shared_ptr 指针相同时,weak_ptr 指针并不会使所指堆内存的引用计数加 1;同样,当 weak_ptr 指针被释放时,之前所指堆内存的引用计数也不会因此而减 1。也就是说,weak_ptr 类型指针并不会影响所指堆内存空间的引用计数

std::unique_ptr:内存的所有者或者说管理者必须是唯一的。如果进入不同的模块或者调用者,那么执行所有权转移。

std::shared_ptr: 内存由多个指针变量共同使用,共同拥有内存的所有权。但是必须杜绝循环拷贝!

std::weak_ptr: 对内存的使用仅仅是访问而已,不涉及其生命周期的管理。
1。也就是说,weak_ptr 类型指针并不会影响所指堆内存空间的引用计数

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/923690.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

shell 编写一个带有进度条的程序安装脚本

需求 使用 shell 写一个 软件安装脚本&#xff0c;带有进度条 示例 #!/bin/bash# 模拟软件安装的步骤列表 steps("解压文件" "安装依赖" "配置设置" "复制文件" "")# 计算总步骤数 total_steps${#steps[]}# 安装进度的初…

JVM——类加载与字节码技术—类加载器+运行期优化

5.类加载器 jdk的类加载器具有层级关系。 启动类加载器》扩展类加载器》应用程序类加载器》自定义类加载器 对应类加载器只会负责加载对应目录的类。 双亲委派上级机制 应用程序类加载器加载一个类之前会先查询上级加载器是否已经加载过了该类。然后再让上级询问上上级。都…

代码随想录算法训练营第四十四天|LeetCode 309,714

目录 LeetCode 309.最佳买卖股票时机含冷冻期 动态规划五步曲&#xff1a; 1.确定dp[i][j]的含义 2.找出递推公式 3.初始化dp数组 4.确定遍历方向 5.打印dp数组 LeetCode 714.买卖股票的最佳时机含手续费 动态规划五步曲&#xff1a; 1.确定dp[i]的含义 2.找出递推公式 3.初始…

项目构建工具:CMake的核心用法

Golang有go mod、Python有pip、Java有maven。但C语言没有这么好用的包管理工具。当然Conan大概可以算是一个&#xff0c;但其也有自身的局限性&#xff0c;使用起来并不简单。 这就导致我们在写C代码的时候&#xff0c;老是要把心思放在怎么构建项目上。比如有一个项目&#x…

重磅!亚马逊将于10月再次举行秋季会员大促!

今年亚马逊7月份的Prime Day大促出乎卖家意料&#xff0c;效果出奇之好&#xff0c;大促确实有提振销量和信心的奇效。 而在近期&#xff0c;亚马逊宣布&#xff0c;将在今年10月&#xff0c;继续为亚马逊Prime会员带来“Prime秋季会员大促”。 19个国家&#xff08;包括澳大…

使用BeanShell写入内容到文件【JMeter】

一、前言 ​ 在我们日常工作中&#xff0c;可能会遇到需要将请求返回的数据写入到文件中。在我们使用JMeter进行性能测试时&#xff0c;就经常能够遇到这种情况。要想达到这种目的&#xff0c;我们一般采取BeanShell后置处理器来将内容写入到文件。 二、提取 ​ 在目前大多数的…

使用代理突破浏览器IP限制

一、实验目的: 主要时了解代理服务器的概念&#xff0c;同时如何突破浏览器IP限制 二、预备知识&#xff1a; 代理服务器英文全称是Proxy Server&#xff0c;其功能就是代理网络用户去取得网络信息。形象的说&#xff1a;它是网络信息的中转站&#xff0c;特别是它具有一个cac…

【Python】从入门到上头—Python基础(2)

文章目录 一.基础语法1.编码2.标识符3.保留字4.注释5.行与缩进6.多行语句7.数字(Number)类型8.字符串(String)9.空行10.等待用户输入11.同一行显示多条语句12.多个语句构成代码组13.print 输出14.import 与 from...import 二.基本数据类型1.变量和赋值2.多个变量赋值3.标准数据…

win10某个软件字体模糊修复

1、在桌面找到该软件&#xff0c;右键选择属性&#xff0c;如下&#xff1a; 2、打开后选择兼容性--更改高DPI设置。 3、点击高DPI缩放替代--应用程序。 4、点击应用&#xff0c;然后退出属性设置。重新打开软件&#xff0c;发现软件字体变得清晰了。

MySQL 保存日期用哪种数据类型

写在前面 在设计数据库表时不可避免的需要用到时间类型&#xff0c;到底选择那种数据类型来表示时间是一个值的讨论的问题&#xff0c;本文就一起来看下&#xff01; 1&#xff1a;能用哪些数据类型 1:字符串&#xff1a;不要用,占用空间大&#xff0c;至少需要19个字节&…

STM32CubeMx配置HAL库编码器测速

编码器概述 编码器是一种用来测量机械旋转或位移的传感器。它能够测量机械部件在旋转或直线运动时的位移位置或速度等信息&#xff0c;并将其转换成一系 列电信号。按照读出方式编码器可以分为接触式和非接触式两种&#xff1b;按照工作原理编码器可分为增量式和绝对式两类。编…

全局ID生成方式

全局ID生成方式 目录 1. 全局唯一id介绍 1.1 特点 2. 常见的全局唯一id生成策略 2.1 利用数据库自增字段生成id2.2 UUID2.3 Redis生成id2.4 zookeeper生成ID2.5 Twitter的snowflake算法 3. 面试题目&#xff1a;实现一个全局的ID生成器&#xff0c;注意线程安全 3.1 单例模式…

【PCL-9】AABB包围盒

当一个物体边与坐标轴平行时&#xff0c;生成的ABB最小外接立方体有偏差&#xff0c;故这里采用AABB算法。 示例代码&#xff1a; #include <pcl/features/moment_of_inertia_estimation.h> #include <vector> #include <pcl/io/pcd_io.h> #include <pc…

在 Pytorch 中使用 TensorBoard

机器学习的训练过程中会产生各类数据&#xff0c;包括 “标量scalar”、“图像image”、“统计图diagram”、“视频video”、“音频audio”、“文本text”、“嵌入Embedding” 等等。为了更好地追踪和分析这些数据&#xff0c;许多可视化工具应运而生&#xff0c;比如之前介绍的…

机器学习十大算法之七——随机森林

0 引言 集成学习&#xff08;ensemble learning&#xff09;是时下非常流行的机器学习算法&#xff0c;它本身不是一个单独的机器学习算法&#xff0c;而是通过在数据上构建多个横型&#xff0c;集成所有模型的建模结果&#xff0c;基本上所有的机器学习领域都可以看到集成学习…

华为OD机试 - 连续字母长度 - 字符串(Java 2023 B卷 100分)

目录 专栏导读一、题目描述二、输入描述三、输出描述1、输入2、输出3、说明4、再输入5、输出6、说明 四、解题思路五、Java算法源码六、效果展示1、输入2、输出3、说明 华为OD机试 2023B卷题库疯狂收录中&#xff0c;刷题点这里 专栏导读 本专栏收录于《华为OD机试&#xff08…

混币器——隐私交易的天堂,还是洗钱犯罪的聚集地?

据美国财政部官网&#xff0c;Tornado Cash 联创 Roman Storm 已被 FBI 和国税局逮捕&#xff0c;罪名是串谋洗钱、串谋经营未经许可的资金传输业务以及串谋违反制裁规定&#xff0c;另一创始人 Roman Semenov仍然在逃。 FBI局长Christopher A. Wray说&#xff1a;“今天的公告…

动物体外受精手术VR模拟仿真培训系统保证学生及标本的安全

奶牛是养殖业主要的资源&#xff0c;因此保证奶牛的健康对养殖业的成功和可持续发展具有重要已用&#xff0c;奶牛有一些常见易发病&#xff0c;一旦处理不当&#xff0c;对奶牛业都会造成较大的经济损失&#xff0c;传统的奶牛手术培训实操难度大、风险高且花费大&#xff0c;…

[管理与领导-43]:IT基层管理者 - 个人管理 - 管理中从角色定位迈步

前言&#xff1a; 管理者的“四位” &#xff1a; ‣ 定位——在什么位置做什么事情&#xff1b; ‣ 到位——全力以赴把事情做好&#xff1b; ‣ 不越位——不要把别人的工作做了&#xff1b; ‣ 补位——同事临时“缺位” &#xff0c;及时补位&#xff0c;提升效率&…

前端(十四)——DOM节点操作手册:你需要了解的一切

&#x1f642;博主&#xff1a;小猫娃来啦 &#x1f642;文章核心&#xff1a;DOM节点操作手册&#xff1a;你需要了解的一切 文章目录 前言DOM基础知识操作现有节点创建新节点遍历节点树修改节点属性和样式事件处理实践应用动态创建表格动态更新列表 前言 DOM&#xff08;文档…