C++ - vector 的相关练习

目录

前言

1、题1 只出现一次的数字 :

解法一:遍历

参考代码:

解法二:按位异或

参考代码:

解法三:哈希表

参考代码:

2、题2 杨辉三角:

参考代码:

总结


前言

路漫漫其修远兮,吾将上下而求索;


大家可以自己先尝试做一下:

136. 只出现一次的数字 - 力扣(LeetCode)

118. 杨辉三角 - 力扣(LeetCode)


1、题1 只出现一次的数字

136. 只出现一次的数字 - 力扣(LeetCode)

解法一:遍历

利用双指针,一个指针定位一个指针去遍历后续的数字看是否有重复的;

参考代码:

    int singleNumber(vector<int>& nums) {int n = nums.size();if(n==1) return nums[0];//解法一:遍历for(int i = 0;i<n;i++){int flag = 1;for(int j = 0;j<n;j++){if(j!=i && nums[i] == nums[j]) flag = 0; }if(flag) return nums[i];}return 0;//此处的返回没有意义,随便返回就可以了}

解法二:按位异或

按位异或的特点:相同为0,相异为1;非空数组nums 中只有一个数字出现了1次,其余的均出现了2次,将nums 中的数据全部进行按位异或,相同的数据抵消就会得到那个只出现一次的数;

参考代码:

    int singleNumber(vector<int>& nums) {//按位异或int ret = 0;for(auto e: nums) {ret ^= e;}return ret;}

解法三:哈希表

将nums 中的数据放入hash 之中,看哪一个数字出现了一次即可;

参考代码:

    int singleNumber(vector<int>& nums) {//hashunordered_map<int,int> hash;//<数据,出现的次数>for(auto e: nums){hash[e]++;}for(auto e:hash){if(e.second == 1) return e.first;}return 0;//随便返回一个}

2、题2 杨辉三角:

118. 杨辉三角 - 力扣(LeetCode)

如果用C语言解决的话,需要返回一个二级指针:

本题用C语言做会非常恶心,可以将杨辉三角想象成二维数组,只是不同的是它不是 m*n 的每一行的数据个数均相等的,杨辉三角的每一行的个数是变化的;

用C语言不能直接静态开辟一个二维数组,只能通过动态开辟的方式;

Q:如何动态开辟一个二维数组?

  • 将杨辉三角想象成一个直角三角形;杨辉三角画成等腰三角形其本质是一个逻辑结构(想象出来的结构);

  • 用C语言做动态开辟数组:先开辟指针数组,然后造一个循环开辟每一行;并且释放的时候也要注意,不能直接释放指针数组,需要写一个循环先将指针数组中所指向的数组先释放(先释放局部再释放整体);

由于C语言只支持一次即返回一个值,而如果想要返回多个值,想让别人拿到该数组的大小只能通过传址传参;在leetcode 之中要写通用的代码,凡是返回数组(返回指向该数组的指针),就得告诉这个数组有多少行,此时写测试用例的时候,每个题都要有每个题的情况;

因为返回一个一维数组需要知道这个一维数组中有多少个数据,同理,返回一个二维数组就需要知道二维数组有多少行,并且一行中有多少个数据;所以其第三个参数,指的是所要返回这个二维数组每一行中有多少个数据;

Q:第三个参数为什么是二级指针呢?

  • 二维数组中每一行的数据个数可能是不同的,需要开辟一块空间来记录每一行的数据个数;所以就需要传一个地址的地址,即二级指针;

我们此处用C++来解决:

Q: 如何理解 vector<vector<int>> ?

  • 在vector 中存放vector<int> ; vector 的底层:
template<class T>
class vector
{
private:T* _a;size_t _size;size_t _capacity;
};

Q: vector<vector<int>>是如何开辟需求的二维数组?

	vector<vector<int>> vv(numRows);//开辟numRows行for (int i = 0; i < numRows; ++i)//开辟每一行{vv[i].resize(i + 1, i);}

vector<vector<int>> 会实例化出两个类,vector<int> 是一个类,而vector<vector<int>> 是另外一个类;

vector<int> 实例化:

vector<vector<int>> 实例化:

类模板给不同的模板参数就会生成不同的类型;这两个虽然是从同一个模板中实例化出来的,但是他们的类型不同,一个是 int  ,一个是 vector<int>;

vector<vector<int>> 是一个对象数组其每一个位置上是一个 vector<int> 对象;

我们在开辟每一行的时候用resize 进行初始化,而并非使用reserve , 这是因为reserve 只会开辟空间而并未插入数据;而resize ,当 n>capacity  或 size<n<capacity 的时候会插入数据,相当于用resize 既可以开辟空间又会初始化;

需要注意的是,已经存在的对象想要初始化就只能使用resize

一个vector 想要初始化有两种方式:

  • 1、在构造的时候进行初始化;
  • 2、构造之后利用resize 进行初始化;

基于杨辉三角的特点,我们需要将开辟的二维数组中的空间均初始化为1,如下:

而接下来就需要处理杨辉三角中其他剩余的值了;访问 vector<vector<int>> 中的数据可以通过二维数组的访问形式进行访问: vv[i][j] , 但是其底层与二维数组的访问完全不同

在回答“ vv[i][j]的底层与二维数组的访问完全不同” 的问题之前,我们先了解一下C语言中二维数组的两种开辟方式:

对于二维数组:eg.int aa[10][5] , 10 行 5 列的二维数组本质上也是一维数组;

  • 1、动态开辟二维数组需要进行转换;
	int* aa = (int*)malloc(sizeof(int*) * N);for(int i = 0; i < N; ++i){aa[i] = (int*)malloc(sizeof(int) * (i + 1));}

aa 作为二维数组数组名,表示该数组的首元素地址,即指向该指针数组;aa[i] 则是访问指针数组中的所对应的数据,而指针数组的元素本身就是一级指针,那么 aa[i][j] 就是两次解引用,访问到了二维数组中的数据;动态开辟的二维数组是两次指针的解引用,先进行第一层的解引用拿到指针数组中的元素,再进行第二层的解引用,拿到真实存放的数据;

  • 2、静态开辟的二维数组,是转换成一个一维数组;

eg.int aa[10][5];

C语言中的静态二维数组其实在底层其实是一个一维数组,那么 int aa[10][5];是一个有50个int 类型空间的一维数组,即一次解引用就可以解决(会通过一些计算来实现一次解引用);

总之,动态开辟和静态开辟是不一样的;

C++中,对于vv[i][j]而言,是两次函数调用对于C语言来说,静态开辟的一维数组或者二维数组均是一次解引用实现数据的访问,数组的访问本质上均会转换成指针的访问,所以C语言的访问数组中的元素一定会转换成对指针的解引用;

Q:vv[i][j] 如何转换成两个函数调用?

  • 首先,vv[i][j] 会转化成 vv.operator[](i).operator[](j) ;其中 vv.operator[](i) 返回的是 vector<int> 的对象,而vector<int>.operator[](j) 返回值为 int 对象相当于第一个 operator[] 的调用返回了vector<int> 对象又会作为下一次调用 operator[] 的左操作数,此时返回值为 int 类型的对象;于是乎就相当于拿到了第 i 行第 j 个对象;

Q: 相较于我们之前使用的二维数组(C语言中的二维数组),此处使用vector<vector<int>> 的好处是什么?

  • vector<vector<T>> 的功能更加强大在C语言中以前定义的静态数组,静态数组中的每一行的数据个数均是固定的,由于C语言不支持变长数组,其行、列必须是常量,且无论是申请还是释放都需要亲历亲为,比较麻烦;但是倘若使用 vector<vector<>> ,便就不存在这样的问题,无需管释放(C++中会自动调用析构函数),并且其每一行的数据个数为多少均无所谓, 即不会强制每一行的数据个数均需要一样;

vv[i][j] 看似有两个[ ], 实际上结合底层的角度它是调用了两个类实例化出来的operator[] ,而这两个类又是由 vector<T> 实例化出来的。由 vector<T> 实例化出来两个类 vector<int> 和 vector<vector<int>> ,然后再实例化其成员函数;

解题:

 

需要从第2行开始遍历,而一有 vv.size() 行;

对于每一行元素访问的控制j ; 每一行的数据个数是不固定的,从每一个 vector<vector<int>> 对象的 _size 可以得知每一行中数据的个数,即 vv[i].size() 为第 i 行中的数据个数;对于杨辉三角来说,其每一行的第一个和最后一个无需进行访问,我们在开辟空间初始化的时候就可以完成;

杨辉三角的计算规则:

  • 将杨辉三角看作是一个直角三角形:

通过观察杨辉三角的计算规则和下标的关系,我们可以得到: [i,j] = [i-1 , j] + [i-1 , j-1];

参考代码:

    vector<vector<int>> generate(int numRows) {vector<vector<int>> vv(numRows);for(size_t i = 0;i<numRows;++i){vv[i].resize(i+1,1);}//填for(int i = 2;i<vv.size();++i)//从2行开始{for(int j = 1; j<vv[i].size()-1;++j){//第一个和最后一个不用填vv[i][j] = vv[i-1][j] + vv[i-1][j-1];}}return vv;}

总结

1、在C++中中,vector<vector<int>> 用vv[i][j] 访问数据会转化调用两个函数,即 vv.operator[](i).operator[](j)

2、其中 vv.operator[](i) 返回的是 vector<int> 的对象,而vector<int>.operator[](j) 返回值为 int 对象相当于第一个 operator[] 的调用返回了vector<int> 对象又会作为下一次调用 operator[] 的左操作数,此时返回值为 int 类型的对象;于是乎就相当于拿到了第 i 行第 j 个对象;

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

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

相关文章

JDK 1.8 Stream API:集合流处理深度解析

JDK 1.8 Stream API&#xff1a;集合流处理深度解析 摘要&#xff1a;Stream API 是 JDK 1.8 的革命性特性&#xff0c;它将集合操作从传统迭代升级为声明式函数式处理。Stream API三个阶段&#xff08;创建→中间操作→终端操作&#xff09;详解流处理机制&#xff0c;辅以代…

2025学年湖北省职业院校技能大赛 “信息安全管理与评估”赛项 样题卷(二)

2025学年湖北省职业院校技能大赛 “信息安全管理与评估”赛项 样题卷&#xff08;二&#xff09; 第一部分&#xff1a;第二部分&#xff1a;网络安全事件响应、数字取证调查、应用程序安全任务书任务 1&#xff1a;应急响应&#xff08;可以培训有答案&#xff09;任务 2&…

AiPy实战(5):效率革命!5分钟构建行业分析报告

在当今数字化时代&#xff0c;数据呈指数级增长&#xff0c;行业分析报告对于企业的决策制定愈发关键。传统上&#xff0c;撰写一份行业分析报告&#xff0c;需要分析师耗费大量时间从各类数据库、新闻资讯平台、行业报告中手动收集数据&#xff0c;再进行整理、分析和撰写&…

docker小白自存-windows系统通过docker安装n8n-nodes-puppeteer

n8n上直接在社区下载puppeteer节点&#xff0c;使用时会报错说没有chromium依赖。 找到了n8n-nodes-puppeteer的github试图解决 根据他的docker安装指南执行&#xff0c;运行容器时会报exec /docker-custom-entrypoint.sh: no such file or directory &#xff08;明明文件都有…

脚本shebang的作用与使用方法

#!&#xff08;称为 shebang 或 hashbang&#xff09;是脚本文件开头的前两个字符&#xff0c;用于告诉操作系统应该使用哪个解释器来执行该脚本。 核心作用&#xff1a; 指定解释器&#xff1a; 明确告诉系统运行这个脚本时应该调用哪个程序&#xff08;解释器&#xff09;来…

【大模型学习 | BERT 量化学习 (1)】

BERT 情感分析 一、 数据集加载与模型训练 from transformers import BertTokenizer, BertForSequenceClassification, Trainer, TrainingArguments from datasets import load_dataset import torch import numpy as np from sklearn.metrics import accuracy_score mode_na…

用低通滤波优化串口或485 通信指示灯电路

常见的通信指示灯电路就是简单的把LED 连到TXD 和RXD 上&#xff0c;一有动静就闪一下。问题是&#xff0c;如果波特率很高&#xff0c;一次通信时间很短&#xff0c;相当于占空比很低&#xff0c;LED 闪烁的亮度就很弱&#xff0c;不容易观察。比如MODBUS 通信&#xff0c;波特…

【纯干货】调整word目录中的行距以及右对齐页码

1.问题展现 目录生成会遇到一些奇葩现象 所以到了展现技术力的时候了【doge】 2.解决word目录中的行距问题 选中目录中的文字-》段落 此时你可能勾选了图片中的一个以上&#xff0c;把他们都取消了&#xff0c; 由于一个目录的标题对应一个样式&#xff0c;第一个也可以取消 …

pandas 优雅处理值类型为list的列的csv读写问题

文章目录 直接存储join list 变成字符串存储json.dumps序列化存储以及json.loads反序列化读取总结 之所以分析这个问题,是因为读者在跟第三方数据供应商对接数据的时候,老是会遇到数据加载都会出错的问题,其中一个原因就是list类型数据没有正确储存,于是笔者在这篇文章里面详细…

一种解决 OpenWrt 安装 docker 之后局域网的设备之间无法互相访问通信的方法

文章目录 一、问题背景二、解决方案&#xff08;方法一&#xff09;修改全局设置的 转发&#xff08; forward&#xff09; 为 接受&#xff08;ACCEPT&#xff09;&#xff08;方法二&#xff09;设置 net.bridge.bridge-nf-call-iptables0 并将 docker 的容器网络设置为host …

Leetcode百题斩-贪心

贪心也是一个很有意思的专题&#xff0c;能遇到很多神奇的思路。 但这个专题&#xff0c;leetcode也没放Hard&#xff0c;果然是怕这种玄学专题上点难度大家罩不住。那就很快了&#xff0c;直接过 763. Partition Labels[Medium] 思路&#xff1a;将字母串分组&#xff0c;相…

基于多径信道的分集接收技术性能优化与仿真分析

基于多径信道的分集接收技术性能优化与仿真分析 一、多径信道建模与仿真 1. 多径信道建模(MATLAB实现) classdef MultipathChannel < handlepropertiesSampleRate = 1e6; % 采样率 (Hz)MaxDoppler = 100; % 最大多普勒频移 (Hz)DelayVector = [0

LeetCode 713.乘积小于K的子数组

给你一个整数数组 nums 和一个整数 k &#xff0c;请你返回子数组内所有元素的乘积严格小于 k 的连续子数组的数目。 示例 1&#xff1a; 输入&#xff1a;nums [10,5,2,6], k 100 输出&#xff1a;8 解释&#xff1a;8 个乘积小于 100 的子数组分别为&#xff1a;[10]、[5…

打破网络安全孤岛:实现防御数据协作

作者&#xff1a;来自 Elastic Crossley McEwen, Oksana Abramovych 现代网络战场不再受组织边界的限制。在各类防御网络中&#xff0c;关键的结构化、非结构化和半结构化数据分布在不同的专业环境中&#xff0c;形成孤岛 —— 从机密情报系统到作战指挥平台&#xff0c;再到战…

给定一个没有重复元素的数组,写出生成这个数组的MaxTree的函数

题目&#xff1a; 给定一个没有重复元素的数组arr&#xff0c;写出生成这个数组的MaxTree的 函数&#xff0c;要求如果数组长度为N&#xff0c;则时间复杂度为O(N)、额外空间复杂度 为O(N)。 一个数组的MaxTree定义如下。 ● 数组必须没有重复元素。 ● MaxTree是一棵二叉…

iOS 抓包实战:时间戳偏差导致的数据同步异常排查记录

“这条数据不是我填的”“我的更新被覆盖了”“两个设备显示不一致”——这些是产品上线后最令人头疼的反馈。 最近我们在一次用户同步问题排查中&#xff0c;发现表面是“数据丢失”问题&#xff0c;实则是多端数据提交时间戳处理不一致&#xff0c;导致后台认为老数据为新&a…

一款支持多日志器、多级别、多落地方式的同异步日志系统

文章目录 简介项目特点项目实现基础功能模块实现文件操作以及日期时间获取日志等级日志信息描述 异步功能模块实现缓冲区实现异步线程实现 核心功能模块实现日志格式解析落地操作实现日志器实现 测试测试环境测试参数测试结果性能分析 附件 简介 在现代软件开发与系统运维领域…

加固笔记本在户外勘探行业的应用:探索与科技的融合

在自然资源勘探、地质调查、石油天然气开发、矿产资源测绘等户外勘探行业中&#xff0c;作业环境常常复杂多变&#xff1a;风沙漫天的戈壁、雨雪交加的山区、湿热潮湿的丛林&#xff0c;甚至是极寒与高温并存的极端气候条件。面对这些挑战&#xff0c;普通的办公设备早已无法胜…

MySQL 连接指定端口后,为什么实际仍是 3306?

文章目录 MySQL 连接指定端口后&#xff0c;为什么实际仍是 3306&#xff1f;问题现象复现原因分析没有指定 -h&#xff0c;默认走的是本地 Unix Socket多实例环境中未显式指定目标地址 正确的连接方法方法一&#xff1a;添加 -h 127.0.0.1方法二&#xff1a;添加 --protocolTC…

【Android当用户两次打断息屏操作后,屏幕将会在10分钟内无法熄灭并持续点亮(关闭Android13新增的dim功能)】

UndimDetectorWakeLock持锁导致屏幕不灭问题处理SOP 问题描述 在Android T版本中&#xff0c;系统新增了SCREEN_BRIGHT_WAKE_LOCK&#xff08;UndimDetectorWakeLock&#xff09;机制。当设备处于低亮度&#xff08;dim&#xff09;状态时&#xff0c;用户两次打断屏幕熄灭操…