C++ STL库之Vector简介及例题(哈希表)(一)

C++ STL库之Vector简介及例题(哈希表)(一)

Vector是一个能够存放任意类型的动态数组,能够增加和压缩数据。

特性1:顺序容器中的元素按照严格的线性顺序排列,可以通过元素的下标访问对应的元素。

特性2:支持对序列中的任意元素进行快速直接查询,可以在序列末尾相对快速地添加/删除元素的操作,所以不知道自己所需的数组大小时,可以用Vector以节约空间。

注意: Vector容器的用法有很多,内置算法函数也有很多,这里就不一一介绍了,就写一些常用的好理解的,如果后面遇到了我会在文章里具体解释。

一、初始化

使用vector容器时需要声明头文件#inlcude <vector>;

vector容器可以是多种数据形式例如int / char / string / 自定义类型 / 结构体类型等等

具体初始化方法如下代码及解释所示:

#include <vector>	// 头文件 #include <vector>;
#include <iostream>
using namespace std;

int main() {
   

	// 限制整形数组长度为10,默认值为0
	vector<int> vec_int_limit(10);

	// 不限制数组长度
	vector<int> vec_int;

	// 直接给数组赋值
	vector<int> vec_int_nums{
    1,2,3,4,5,6 };

	// 建立string类型数组,长度为10,每个默认为"uhao"
	vector<string> string_array(10, "uhao");

	// 建立二维数组,可直接赋值
	vector<vector<int>> two_array{
    {
   1,2,3},{
   4,5,6} };

	// 从原数组中取一段值赋值,goal_array数组结果是{6,5,4}
	// 如下代码区间为:[ original_array.begin() , original.begin()+3 )
	vector<int> original_array{
    6,5,4,3,2,1 };
	vector<int> goal_array(original_array.begin(),original_array.begin() + 3);

	return 0;
}

二、数值操作

Vector容器有很多种函数可以对内容进行不同操作,这里就介绍一些常用的,后续用到别的会再解释。

创建一个数组并直接赋值:vector<int> vec{ 7,5,3,1,2,0 };

访问数组下标中的元素:vec[1]; // 二维数组同理vec[num1][num2]

获取数组下标中的元素,同 vec[1]vec.at(1);

在尾部添加一个元素 8:vec.push_back(8);

删除最后一个元素:vec.pop_back();

获取vector数组元素个数,即长度:vec.size();

获取数组第一个元素的指针vec.begin();

获取数组最后一个元素+1的指针:vec.end();

获取数组第一个元素值:vec.front();

获取数组最后一个元素值:vec.back();

与数组other_array交换数据(可以说是用other_array替换vec):vec.swap(other_array);

判断是否为空,为空返回1,不为空返回0:vec.empty();

第i+1个元素前插入数据e:vec.insert(vec.begin() + i , e);

倒数第i个元素前面插入e:vec.insert(vec.end() - i , e);


例题

力扣经典第1题《两数之和》

给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 target 的那两个整数,并返回它们的数组下标。

你可以假设每种输入只会对应一个答案。但是,数组中同一个元素在答案里不能重复出现。

示例 1:

输入:nums = [2,7,11,15], target = 9
输出:[0,1]
解释:因为 nums[0] + nums[1] == 9 ,返回 [0, 1] 

题解

思路 1

用两个for循环,暴力破解,这个方法比较简单就不写解析了,代码如下:

vector<int> twoSum(vector<int>& nums, int target) {
   
        int n = nums.size();
        for (int i = 0; i < n; ++i) {
   
            for (int j = i + 1; j < n; ++j) {
   
                if (nums[i] + nums[j] == target) {
   
                    return {
   i, j};
                }
            }
        }
        return {
   };
    }

// 来源:力扣(LeetCode)

 

思路 2

用两个for循环的时间复杂度比较高,所以如果我们如果能够先确定一个数字,然后在数组余下的数字中迅速找出target-x,那么我们的效率肯定会翻倍;

所以我们这个时候就会想到**哈希表。**

哈希表简析

哈希表是一种数据结构,它可以提供非常快速的数据插入和查找操作。它通过一个叫做哈希函数的过程,将存储的数据项与一个特定的索引关联起来,这个索引指示了数据项在表中的位置。

C++哈希表初始化

#include <iostream>
#include <unordered_map> // 哈希表头文件
using namespace std;

int main()
{
   
    unordered_map<int, int> hashMap;  // 创建哈希表
	// 进行赋值
    hashMap[1] = 10;      
    hashMap[2] = 20;
    hashMap[3] = 30;
	//	it->first 用于获取当前迭代器it指向的元素下标
    //	it->second 用于获取当前迭代器it指向的元素值
    for (auto it = hashMap.begin(); it != hashMap.end(); it++) {
   
        cout << "key:" << it->first << " value:" << it->second << endl;
    }
	/*
	输出结果为:
	key:1 value:10
	key:2 value:20
	key:3 value:30
	*/
    return 0;
}

C++哈希表基本操作

1. 插入操作

// 使用下标操作符插入元素
hashMap[key] = value;

// 使用insert()方法插入元素
hashMap.insert({
   key, value});

2. 删除操作

hashMap.erase(key); // 删除指定元素key

3. 访问

hashMap[key]; // 直接访问 或用迭代器,见上哈希表简析代码

★4. 判断元素是否存在

// 方法1 根据哈希表的特性,如果一个元素被注册过也就是存在,则count值为1,否则为0
if(hashMap.count(key) > 0){
   
    // 存在
}
else{
   
    // 不存在
}

// 方法2 使用find函数,如果查找的key不存在于哈希表,则返回值与hashMap.end()相等,反之同理
if (hashMap.find(key) != hashMap.end()) {
   
	cout << "存在";
}
else {
   
    cout << "不存在";
}


大致了解了哈希表的应用之后,我们可以得出以下优化后的代码:

vector<int> twoSum(vector<int>& nums, int target) {
   
     unordered_map<int, int> m;
     for (int i = 0; i < nums.size(); ++i) {
   
         if (m.count(target - nums[i])) {
   
             return {
   m[target - nums[i]], i};
         }
         m[nums[i]] = i;
     }
     return {
   };
    }

代码解析

1. 创建一个空的哈希表 unordered_map<int, int> m; 用来存储数组值到索引的映射。
2. 使用一个for循环,遍历整个输入数组 nums
3. 在循环内部,使用 if 语句检查哈希表中是否存在一个键值对,其键(target - nums[i])是目标值与当前元素值的差。
4. 如果这样的键存在,说明我们找到了两个数,它们的和等于目标值:target - nums[i] 是之前某个元素的值,nums[i] 是当前元素的值。这时,我们返回一个包含两个下标的数组:先前元素的下标 m[target - nums[i]] 和当前元素的下标 i
5. 如果没有找到,则将当前元素的值和它的下标 i 加入到哈希表中,即 m[nums[i]] = i;
6. 如果整个数组都遍历完了还没有找到这样的两个数,则函数返回一个空数组 return {};
 
基本上,这段代码利用哈希表存储已经遍历过的元素的值和对应的下标,借助这个表我们能在O(1)的时间复杂度内查找到 target - nums[i]。因此,整个函数的时间复杂度是O(n),其中n是数组 nums 的长度。这是一个高效的解决方案,因为它避免了使用两个嵌套循环,这在最坏的情况下会导致O(n^2)的时间复杂度。

相关推荐

  1. C++ STLVector简介例题)(

    2024-01-30 22:16:04       54 阅读
  2. STL容器的补充——桶实现

    2024-01-30 22:16:04       46 阅读
  3. 数据结构-

    2024-01-30 22:16:04       43 阅读
  4. Leetcode刷题(

    2024-01-30 22:16:04       31 阅读
  5. Rust语言

    2024-01-30 22:16:04       63 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-01-30 22:16:04       94 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-01-30 22:16:04       101 阅读
  3. 在Django里面运行非项目文件

    2024-01-30 22:16:04       82 阅读
  4. Python语言-面向对象

    2024-01-30 22:16:04       91 阅读

热门阅读

  1. python中for循环的几个现象

    2024-01-30 22:16:04       58 阅读
  2. rust 泛型

    2024-01-30 22:16:04       71 阅读
  3. Ubuntu 下进行系统备份与迁移

    2024-01-30 22:16:04       59 阅读
  4. HarmonyOS--@ObjectLink和@Observed

    2024-01-30 22:16:04       67 阅读
  5. vue 和 react技术选型

    2024-01-30 22:16:04       50 阅读
  6. 51单片机智能小车

    2024-01-30 22:16:04       50 阅读
  7. 多线程面试合集

    2024-01-30 22:16:04       55 阅读
  8. 华为策略路由+NQA配置

    2024-01-30 22:16:04       50 阅读