先了解一下vector,vector是C++标准模板库中的部分内容,它是一个多功能的,能够操作多种数据结构和算法的模板类和函数库。vector是一个容器,它能够存放各种类型的对象,简单地说,vector是一个能够存放任意类型的动态数组,可以动态改变大小。
什么是vector:
- vector是向量类型
- vector数组是可以存放任意数据类型的动态数组
- 和普通数组类似,可以通过下标对数组中的元素进行引用
vector的基本操作:
声明:
vector<int> vec;
初始化:
vector<int> empty_vec();//空vec
vector<int> vec(3);//大小为3
vector<int> vec2(vec);//声明并用a向量初始化vec向量
int a[5] = {1, 2, 3, 4, 5};
vector<int> vec3(a, a + 5);//将a数组的元素用来初始化vec3向量
vector<int> vec4(&a[1], &a[4]);//将a[1]-a[4]范围内的元素作为vec4的初始值
vector<int> vec5 = {1, 2, 3, 4, 5, 6};
vector<int> vec6(5, -1);//{-1,-1,-1,-1,-1}
添加元素:
vec5.push_back(7);
访问元素:
for (int i = 0; i < v1.size(); i++) {
cout << v1[i] << endl;
v1[i] = 100;
cout << v1[i] << endl;
}
for (vector<int>::iterator iter = vec5.begin(); iter != vec5.end(); iter++) {
cout << *iter << endl;
}
//反向迭代
for (vector<int>::reverse_iterator iter = vec5.rbegin(); iter != vec5.rend(); iter++) {
cout << *iter << endl;
}
插入元素:
std::vector<int> demo{1,2};
//第一种格式用法
demo.insert(demo.begin() + 1, 3);//{1,3,2}
//第二种格式用法
demo.insert(demo.end(), 2, 5);//{1,3,2,5,5}
//第三种格式用法
std::array<int,3>test{ 7,8,9 };
demo.insert(demo.end(), test.begin(), test.end());//{1,3,2,5,5,7,8,9}
//第四种格式用法
demo.insert(demo.end(), { 10,11 });//{1,3,2,5,5,7,8,9,10,11}
删除元素:
vector<int>demo{1, 2, 3, 4, 5};
demo.pop_back();
//删除最后一个元素,大小减一,容量不变
auto iter = demo.erase(demo.begin() + 1);//删除元素 2
// 删除 vector 容器中 pos 迭代器指定位置处的元素,并返回指向被删除元素下一个位置元素的迭代器。
// 该容器的大小(size)会减1,但容量(capacity)不会发生改变
// erase()函数在删除元素时,会将删除位置后续的元素陆续前移,并将容器的大小减 1。
什么是set
set
就是集合,STL的set
用二叉树实现,集合中的每个元素只出现一次(参照数学中集合的互斥性),并且是排好序的(默认按键值升序排列),访问元素的时间复杂度是O(log₂n)。
set基本使用
begin(); // 返回指向第一个元素的迭代器
end(); // 返回指向迭代器的最末尾处(即最后一个元素的下一个位置)
clear(); // 清除所有元素
count(); // 返回某个值元素的个数
empty(); // 如果集合为空,返回true
equal_range(); //返回集合中与给定值相等的上下限的两个迭代器
erase() //删除集合中的元素
find() //返回一个指向被查找到元素的迭代器
get_allocator() //返回集合的分配器
insert() //在集合中插入元素
lower_bound() //返回指向大于(或等于)某值的第一个元素的迭代器
key_comp() //返回一个用于元素间值比较的函数
max_size() //返回集合能容纳的元素的最大限值
rbegin() //返回指向集合中最后一个元素的反向迭代器
rend() //返回指向集合中第一个元素的反向迭代器
size() //集合中元素的数目
swap() //交换两个集合变量
upper_bound() //返回大于某个值元素的迭代器
value_comp() //返回一个用于比较元素间的值的函数
例题1:349. 两个数组的交集
菜鸡的思路:
桶排序。
菜鸡的代码:
class Solution {
public:
vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {
int array1[1001] = {0}, array2[1001] = {0};
vector<int> intersection;
for (int i : nums1) {
array1[i] = 1;
}
for (int i : nums2) {
if (array1[i] && !array2[i]) {
intersection.push_back(i);
}
array2[i]++;
}
return intersection;
}
};
结果:
例题2:剑指 Offer 06. 从尾到头打印链表
菜鸡的思路:
vector容器反向迭代遍历。
菜鸡的代码:
class Solution {
public:
vector<int> reversePrint(ListNode* head) {
vector<int> normalVect, resultVect;
ListNode* p = head;
while (p) {
normalVect.push_back(p->val);
p = p->next;
}
for (vector<int>::reverse_iterator iter = normalVect.rbegin(); iter != normalVect.rend(); iter++) {
resultVect.push_back(*iter);
}
return resultVect;
}
};
结果:
例题3:905. 按奇偶排序数组
菜鸡思路:
双指针
菜鸡代码:
class Solution {
public:
bool isOdd(int num) {
return num % 2;
}
vector<int> sortArrayByParity(vector<int>& nums) {
int l = 0, r = nums.size() - 1;
while (l < r) {
while (!isOdd(nums[l]) && l < r) {
l++;
}
while (isOdd(nums[r]) && l < r) {
r--;
}
int t = nums[l];
nums[l] = nums[r];
nums[r] = t;
}
return nums;
}
};
例题4:剑指 Offer 53 - I. 在排序数组中查找数字 I
菜鸡思路:
二分查找啊,鸡贼一点就是用自带的方法。如果是老实人就自己写吧。
菜鸡代码:
class Solution {
public:
int search(vector<int>& nums, int target) {
return upper_bound(begin(nums), end(nums), target) - lower_bound(begin(nums), end(nums), target);
}
};
class Solution {
public:
int bSearch(vector<int>& nums, int target, bool low) {
int left = 0, right = (int)nums.size() - 1, result = (int)nums.size();
while (left <= right) {
int mid = (left + right) / 2;
if (nums[mid] > target || (low && nums[mid] >= target)) {
right = mid - 1;
result = mid;
} else {
left = mid + 1;
}
}
return result;
}
int search(vector<int>& nums, int target) {
int left = bSearch(nums, target, true);
int right = bSearch(nums, target, false) - 1;
if (left <= right && right < nums.size() && nums[left] == target && nums[right] == target) {
return right - left + 1;
}
return 0;
}
};
例题5:剑指 Offer 53 - II. 0~n-1中缺失的数字
菜鸡思路:
二分查找啊,或者使用一遍遍历。
菜鸡代码:
//二分
class Solution {
public:
//利用的就是比较该位置的值和其下标值
int missingNumber(vector<int>& nums) {
int left = 0, right = nums.size() - 1;
while (left <= right) {
int mid = (left + right) / 2;
if (nums[mid] == mid) {
left = mid + 1;
} else {
right = mid - 1;
}
}
return left;
}
};
//遍历
class Solution {
public:
//利用减值看哪个缺少
int missingNumber(vector<int>& nums) {
int result = (nums.size() + 1) * nums.size() / 2;
for (int i : nums) {
result -= i;
}
return result;
}
};
例题6:剑指 Offer 62. 圆圈中最后剩下的数字
思考:
这道题里竟然蕴藏着动态规划的思想
代码:
class Solution {
public:
int lastRemaining(int n, int m) {
int x = 0;
for (int i = 2; i <= n; i++) {
x = (x + m) % i;
}
return x;
}
};