题目:在一个长度为 n 的数组 nums 里的所有数字都在 0~n-1 的范围内。数组中某些数字是重复的,但不知道有几个数字重复了,也不知道每个数字重复了几次。请找出数组中任意一个重复的数字。 一、基础知识 1、map和unordered_map(也就是通俗意义上的hash map) 这是C++的STL库实现的两种字典结构,都是通过键值对(key-value)存储数据的,键(key)和值(value)的数据类型可以不同。值(value)可以直接通过键(key)来访问, a.hash_map基于hash table(哈希表)。内部元素无序。 优点: 因为内部实现了哈希表,因此其查找速度非常的快,查找的时间复杂度可达到O(1)(空间换时间) 缺点: 哈希表的建立比较耗费时间 适用处:对于查找问题,unordered_map会更加高效一些,因此遇到查找问题,常会考虑一下用unordered_map
b.map内部实现了一个红黑树(红黑树是非严格平衡二叉搜索树,而AVL是严格平衡二叉搜索树),红黑树具有自动排序的功能,因此map内部的所有元素都是有序的,红黑树的每一个节点都代表着map的一个元素。因此,对于map进行的查找,删除,添加等一系列的操作都相当于是对红黑树进行的操作。map中的元素是按照二叉搜索树(又名二叉查找树、二叉排序树,特点就是左子树上所有节点的键值都小于根节点的键值,右子树所有节点的键值都大于根节点的键值)存储的,使用中序遍历可将键值按照从小到大遍历出来。复杂度与树高相同,即O(logn)。 优点: 有序性,这是map结构最大的优点,其元素的有序性在很多应用中都会简化很多的操作 红黑树,内部实现一个红黑书使得map的很多操作在lgn的时间复杂度下就可以实现,因此效率非常的高 缺点: 空间占用率高,因为map内部实现了红黑树,虽然提高了运行效率,但是因为每一个节点都需要额外保存父节点、孩子节点和红/黑性质,使得每一个节点都占用大量的空间 适用处:对于那些有顺序要求的问题,用map会更高效一些
int main() {
map<int, char> m;
m.insert(pair<int, char>(1, 'a'));
m.insert(pair<int, char>(3, 'b'));
m.insert(pair<int, char>(2, 'c'));
m.insert(pair<int, char>(-1, 'd'));
map<int, char>::iterator it = m.begin();
for (; it != m.end(); it++) {
cout << it->first << ":" << it->second << endl;
}
it = m.find(1);
if (it != m.end()) { cout << "find" << it->second << endl; }
else { cout << "not find" << endl; }
for (map<int, char>::reverse_iterator Rit = m.rbegin(); Rit!=m.rend(); Rit++) {
cout << Rit->first << ":" << Rit->second;
}
return 0;
}
2、vector用法 vector 是向量类型,它可以容纳许多类型的数据,如若干个整数,所以称其为容器。vector 是C++ STL的一个重要成员。
(1) vector<int> a(10);
(2)vector<int> a(10,1);
(3)vector<int> a(b);
(4)vector<int> a(b.begin(),b.begin+3);
(5)int b[7]={1,2,3,4,5,9,8};
vector<int> a(b,b+7);
(1)a.assign(b.begin(), b.begin()+3);
(2)a.assign(4,2);
(3)a.back();
(4)a.front();
(5)a[i];
(6)a.clear();
(7)a.empty();
(8)a.pop_back();
(9)a.erase(a.begin()+1,a.begin()+3);
(10)a.push_back(5);
(11)a.insert(a.begin()+1,5);
(12)a.insert(a.begin()+1,3,5);
(13)a.insert(a.begin()+1,b+3,b+6);
(14)a.size();
(15)a.capacity();
(16)a.resize(10);
(17)a.resize(10,2);
(18)a.reserve(100);
(19)a.swap(b);
(20)a==b;
二、c++参考答案
class Solution {
public:
int findRepeatNumber(vector<int>& nums) {
unordered_map<int, bool> map;
for(int num : nums) {
if(map[num]) return num;
map[num] = true;
}
return -1;
}
};
class Solution {
public:
int findRepeatNumber(vector<int>& nums) {
int i = 0;
while(i < nums.size()) {
if(nums[i] == i) {
i++;
continue;
}
if(nums[nums[i]] == nums[i])
return nums[i];
swap(nums[i],nums[nums[i]]);
}
return -1;
}
};
|