c++ 将deque部分元素赋值给vector_干货 | 名企高频考点之C++ STL 二维vector的写法,先行再列和先列再行遍历...

95752336cb81540d54dac7c4c70eda94.png

点击蓝字关注我哦

a3ae8f39be37ce399223135ddcbcc924.png 以下是本期干货视频 视频后还附有文字版本哦 e1844a09f84425acb02437265ba38e64.png 536e75a0b48650fa406737c5d361b5df.png ▼ 《名企高频考点-C++ STL 二维vector的写法,先行再列和先列再行遍历》 ▼ ps:请在WiFi环境下打开,如果有钱任性请随意

0. 概述

二维数组是日常开发中使用高频的一种管理数据的方式,比如迷宫地图,邻接矩阵等,操作起来也非常方便。在面试中也经常被问到,本文主要对vector构造的二维数组进行说明。

1.传统二维数组的缺陷

传统定义二维数组的方式,采用宏定义给出二维数组的行和列,然后定义出二维数组并对其进行初始化,最后就是对该二维数组进行操作,比如:
#define ROW 5#define COL 5void Test2Array(){  int array[ROW][COL] = { { 0, 1, 0, 0, 0 },                          { 0, 1, 0, 0, 0 },                          { 0, 1, 1, 1, 0 },                          { 0, 1, 0, 1, 0 },                          { 0, 0, 0, 1, 0 } };   // 打印二维数组  for (int i = 0; i < ROW; ++i)  {    for (int j = 0; j < COL; ++j)    {      cout << array[i][j] << " ";    }    cout << endl;  }  cout << endl;  }
该种方式使用起来确实比较方便,但缺陷是:数组被限制死了,只能表示5行5列的数组,但有些情况下需要的可能是动态的二维数组,传统二维数组就无能为力。

2. 使用vector定义二维数组

2.1 矩阵(每行元素个数相同)
(1)元素内容都相同:直接使用vector中vector 来进行构造
int main(){    size_t row, col;    int val;    cin>>row>>col>>val;    // 创建一个row行col列的矩阵,并使用val进行填充    vector<vector<int>> v(row, vector<int>(col, val));    return 0;}

(2)元素内容不同:先创建好矩阵,然后给每行元素依次赋值

int main(){    int row,col;    cin>>row>>col;    // 创建一个row行col列的二维数组,逐个给每行元素进行赋值    vector<vector<int>> v(row, vector<int>(col));    // 将每行的元素赋值为1~col    for(int i = 0; i < v.size(); ++i)    {        for(int j = 0; j < v[i].size(); ++j)        {            v[i][j] = j+1;        }    }    return 0;}

88d4281297df4d34224bb9cc8192f897.png

2.2 动态二维数组
先开辟行,再根据每列中具体元素个数来开辟空间以及给每行元素进行赋值,比如:杨辉三角
/*杨慧三角的前5行0行:11行:1 12行:1 2 13行:1 3 3 14行:1 4 6 4 1观察发现:第0列和对角线全部为1,其余位置为上一行同列元素以及上一行同列前一个元素之和*/void PascalTriangle(int N){  vector<vector<int>> vv;    // 先给出二维数组的行,此时每行还没有空间  vv.resize(N);  for (int i = 0; i < N; ++i)  {        // 将第i行元素个数设置为i+1,初始值用1填充    vv[i].resize(i + 1, 1);    for (int j = 1; j < i; ++j)    {      vv[i][j] = vv[i - 1][j] + vv[i - 1][j - 1];    }  }    // 打印二维数组  for (int i = 0; i < N; ++i)  {    for (int j = 0; j <= i; ++j)    {      cout<" ";    }    cout << endl;  }}

0fa84de886f1231603a8ae2ac2e74df1.png

2.3 不确定行列个数
该种场景也比较常见,从问题给的描述中只知道结果为二维数组,但是二维数组的行列需要根据题目的输入来确定,直接无法确定。 此种方式的常见解法是:先构造一个空的二维数组,然后构造一个一维的不断向二维数组中插入 例如:二叉树的封层遍历

526610d30dc519552ea6a69af68bcc10.png

class Solution {public:    vector<vector<int>> levelOrder(TreeNode* root) {        vector<vector<int>> ret;        if(nullptr == root)            return ret;        queue q;        q.push(root);        while(!q.empty()){            // 为了提高效率,先插入一个空的vector            ret.push_back(vector<int>());            // 拿到数组的最后一行,借助引用直接在最后一行插入            vector<int>& level = ret.back();            // 本层中节点总的个数            size_t size = q.size();            for(int i = 0; i < size; ++i)            {                TreeNode* cur = q.front();                q.pop();                level.push_back(cur->val);                if(cur->left)                    q.push(cur->left);                if(cur->right)                    q.push(cur->right);            }        }        return ret;    }};
2.4 二维数组的误用
用vector创建的二维数组,一般情况下是先给出有多少行,然后再对每行进行操作。最常见的误用就是还没有给每行分配空间,就直接对行进行操作而引起代码崩溃。
void Test2Vector(){  vector<vector<int>> vv;  vv.resize(5);   // 二维数组总共有5行,但是每行现在还没有空间  vv[0][0] = 10;  // 此时直接操作每行中元素时会崩溃}

3. 面试题

二维数组先行后列遍历效率高

还是先列后行遍历效率高?

3.1 先行后列
先行后列是最常见的二维数组的遍历方式,而且效率非常高,因为二维数组的每一行都是一段连续的空间,根据局部性原理,操作系统再访问每个元素时,会将该元素附近多个元素一次性加载到缓存中来提高程序效率。
void Print2Vector(){  // 采用C++11提供的列表初始化构造二维数组,每行元素使用{1,2,3,4,5}进行填充  vector<vector<int>> vv(5, { 1, 2, 3, 4, 5 });  // 常规方式  for (size_t i = 0; i < vv.size(); ++i)  {    for (size_t j = 0; j < vv[i].size(); ++j)    {      cout << vv[i][j] << " ";    }    cout << endl;  }  cout << endl;  // 采用范围for打印  for (auto& rowV : vv){    for (auto e : rowV){      cout << e << " ";    }    cout << endl;  }  cout << endl;}程序输出:1 2 3 4 51 2 3 4 51 2 3 4 51 2 3 4 51 2 3 4 51 2 3 4 51 2 3 4 51 2 3 4 51 2 3 4 51 2 3 4 5
3.2 先列后行 该种方式使用比较少,因为效率比较低,一般情况下适合矩阵使用场景。
void Print2Vector2(){  // 采用C++11提供的列表初始化构造二维数组,每行元素使用{1,2,3,4,5}进行填充  vector<vector<int>> vv(5, { 1, 2, 3, 4, 5 });  // 先行后列  for (size_t row = 0; row < vv.size(); ++row)  {    for (size_t col = 0; col < vv[i].size(); ++col)    {      cout << vv[row][col] << " ";    }    cout << endl;  }  cout << endl;  // 先列后行  for (size_t col = 0; col < vv[0].size(); ++col)  {    for (size_t row = 0; row < vv.size(); ++row)    {      cout << vv[row][col] << " ";    }    cout << endl;  }  cout << endl;}程序输出:1 2 3 4 51 2 3 4 51 2 3 4 51 2 3 4 51 2 3 4 51 1 1 1 12 2 2 2 23 3 3 3 34 4 4 4 45 5 5 5 5

4. 总结

本文主要介绍了vector构造二维数组的常见方式以及遍历,具体如下:

061c8636b8757e00d77dfd8736f4b182.png

相信大家对二维数组的使用有进一步的了解,具体还应该根据实际情况选择合适的构造方式。 最后介绍了二维数组行优先遍历以及列优先的遍历方式,以及两种遍历方式的区别,希望通过本文学习,大家对于二维数组应用可以得心应手,谢谢。 作者:时亮益 审核:王海斌 编辑:比特李哥

43ac88287cdf1d05ceebf2b45b3b188c.png

好看,就要点个"在看"

42478d7a7198dd75150540cef308caa1.gif
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值