set容器
set容器是关键字的简单集合。特别适用于想快速知道某个元素在容器中是否出现情况
在set中每个元素的值都唯一,而且系统能根据元素的值自动进行排序。set中元素的值不能直接被改变。set内部采用的是一种非常高效的平衡检索二叉树:红黑树,也称为RB树(Red-Black Tree)。RB树的统计性能要好于一般平衡二叉树。
set具备的两个特点:
- set中的元素都是排序好的
- set中的元素都是唯一的,没有重复的
set容器中常用的方法
count() 用来查找set中某个某个键值出现的次数
这个函数在set并不是很实用,因为一个键值在set只可能出现0或1次,这样就变成了判断某一键值是否在set出现过了
insert(x) 向容器中插入元素x
erase(x) 删除容器中元素x
begin() 返回set容器的第一个元素 / 返回指向第一个元素的迭代器
end() 返回set容器的最后一个元素
clear() 删除set容器中的所有的元素
empty() 判断set容器是否为空
size() 返回当前set容器中的元素个数
具体编码应用:无重复字符的最长子串
//无重复字符的最长子串
class Solution {
public:
int lengthOfLongestSubstring(string s) {
//滑动窗口方法[)左闭右开 [i,j)
int n=s.size();
set<char> st;
int ans=0;
int i,j;
for( i=0,j=0;i<n && j<n; ){
if(st.count( s[j] )==0 ){ //count()方法判断字符是否出现
st.insert( s[j] );
j++;
ans=max(ans,j-i);
}
else{
st.erase(s[i]); //erase(x)方法删除容器中字符x
i++;
}
}
return ans;
}
};
map容器
map提供一对一的数据处理,<key , value>键值对,其类型可以自己定义,其中第一个成为关键字,第二个称为关键字的值。
map具备的两个特点:
- map中的元素都是排序好的
- map中关键字key不能修改,值value可以修改
- iter->first; //key值
- iter->second; // value值
map容器中常用的方法
1、查找元素 find(x)
当所查找的关键x出现时,它返回数据所在对象的位置,如果沒有,返回iter与end()的值相同,
用于快速查找某个关键字是否出现在map容器中
2、map容器中插入元素
// 定义一个map对象
map<int, char> mp;
// 第一种 用insert函数插入pair
mp.insert( pair<int, char>(0, ‘a’) );
// 第二种 用insert函数插入value_type数据
mp.insert( map<int, char>::value_type(1, 'b') );
// 第三种 用"array"方式插入
mp[2] = 'c';
***注意***
以上三种用法,虽然都可以实现数据的插入,但是它们是有区别的,第一种和第二种在效果上是完成一样的,用insert方法插入数据(个人推荐不用记住第二种方法),但是在数据的插入上涉及到集合的唯一性这个问题,即当map中有这个关键字时,insert操作是不能在插入数据的,但是用数组array方式就不同了,它可以覆盖以前该关键字对 应的值.
mp[2] = 'c';
mp.insert( pair<int, char>(2, ‘a’) ); //这条语句不执行
mp[2] = 'd'; //该语句执行,且改变关键字2的值为d
3、map的遍历
//迭代
map< string,int>::iterator iter;
for(iter = mp.begin(); iter != mp.end(); iter++)
cout<<iter->first<<' '<<iter->second<<endl;//输出的是key value值
//数组形式的遍历 下标从1开始
int nSize = mp.size();
//此处应注意,应该是 for(int nindex = 1; nindex <= nSize; nindex++)
//而不是 for(int nindex = 0; nindex < nSize; nindex++)
for(int nindex = 1; nindex <= nSize; nindex++)
cout<<mp[nindex]<<endl;
//反向迭代
map<string,int>::reverse_iterator iter;
for(iter = mp.rbegin(); iter != mp.rend(); iter++)
cout<<iter->first<<' '<<iter->second<<endl;
4、其它方法
count() 返回指定元素出现的次数
begin() 返回指向map头部的迭代器
end() 返回指向map末尾的迭代器
rbegin() 返回一个指向map尾部的逆向迭代器
rend() 返回一个指向map头部的逆向迭代器
clear() 删除所有元素
erase() 删除一个元素
empty() 如果map为空则返回true
size() 返回map中元素的个数
具体编码应用:无重复字符的最长子串
class Solution {
public:
int lengthOfLongestSubstring(string s) {
//优化的滑动窗口方法[)左闭右开,当遇见重复字符时,将i定位到最大的一位,而不需要逐渐增加i
int n=s.size();
int ans=0;
int i,j;
map<char, int> mp;
for(i=0,j=0;j<n;j++){
//元素存在了
if(mp.find(s[j]) != mp.end()){
i=max(i,mp.find(s[j])->second);
}
ans=max(ans,j-i+1);
mp[s[j]]=j+1; //注意防坑
//如果使用mp.insert( pair<char ,int> (s[j],j+1)) 则无法更改关键值的值,导致算法运行失败
}
return ans;
}
};