您的位置:首页 > 理论基础 > 数据结构算法

数据结构与算法以及刷题leetocde 007 查找表 set和map相关

2018-03-06 19:59 519 查看
之前都是数组的操作,接下来介绍的数据结构是set,map, set 和map是C++中的容器;
首先复习一下set的基本使用,set数据结构内的数据是没有重复数据的,unique#include<set>
#include<iostream>
using namespace std;
int main()
{
int i;
int arr[5] = {0,1,2,3,4};
set<int> iset(arr,arr+5);

iset.insert(5);
cout<<"size:"<<iset.size()<<endl;
cout<<"3 count = "<<iset.count(3)<<endl;
iset.erase(1);

set<int>::iterator ite1 = iset.begin();
set<int>::iterator ite2 = iset.end();
for(;ite1!=ite2;ite1++)
{
cout<<*ite1;
}
cout<<endl;

ite1 = iset.find(3);
if(ite1!=iset.end())
cout<<"3 found"<<endl;

ite1 = iset.find(1);
if(ite1!=iset.end())
cout<<"1 not found"<<endl;
}基本操作是insert(),erase(),find(),change(map)改变map中的值的函数,由于C++中是使用二分搜索树来实现set和map所以插入,删除,查找的时间复杂度都是O(log(n))
关于集合的操作使用leetcode中的题型有:
leetcode 349:求解两个数组的交集class Solution {
public:
vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {
//使用集合数据结构
set<int> unique(nums1.begin(),nums1.end());
set<int> ans;
int i=0;
int size=nums2.size();
for(i=0;i<size;i++){
if(unique.find(nums2[i])!=unique.end()){//uniques.find()返回的是迭代器类型
ans.insert(nums2[i]);
}
}
vector<int> result(ans.begin(),ans.end());
return result;

}
};时间复杂度为O(nlogn)
算法改进:使得时间复杂度为O(n),这时就需要用到两种数据结构 unordered_set和unordered_map,这两种数据结构的底层实现是通过hash表来实现的,所以插入和查找的时间复杂度为O(1)class Solution {
public:
vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {
//使用集合数据结构
unordered_set<int> unique(nums1.begin(),nums1.end());
unordered_set<int> ans;
int i=0;
int size=nums2.size();
for(i=0;i<size;i++){
if(unique.find(nums2[i])!=unique.end()){
ans.insert(nums2[i]);
}
}
vector<int> result(ans.begin(),ans.end());
return result;

}
};

以下是C++中map的基本使用,同样map的底层实现是通过二分搜索树实现的;
//插入元素:
//用insert函數插入pair,成对的插入剪枝对的方式来构建
mapStudent.insert(pair<string, string>("r000", "student_zero"));

//用"array"方式插入
mapStudent["r123"] = "student_first";
mapStudent["r456"] = "student_second";C++中map有点类似于Python中defaultDict高级数据结构,默认值为0
leetcode 350 求两个数的交集,返回含有重复类型的数据
class Solution {
public:
vector<int> intersect(vector<int>& nums1, vector<int>& nums2) {
map<int,int> maps;
vector<int> ans;
int i=0;
int size=nums1.size();
for(i;i<size;i++){
maps[nums1[i]]++;//默认值为0
}
int size2=nums2.size();
for(int j=0;j<size2;j++){
if(maps.find(nums2[j])!=maps.end()){
maps[nums2[j]]--;
if(maps[nums2[j]]>=0)
ans.push_back(nums2[j]);
}
}
return ans;
}
};时间复杂度是O(nlog(n))
算法优化:使用unordered_map来进行构建数据
将map改为unordered_map<int,int>即可

leetcode242:判断一个字符串是否是自身变换的字符串class Solution {
public:
bool isAnagram(string s, string t) {
//使员工查找表数据结构来实现相应 hash
map<char,int> maps;
int i=0;
int size=s.size();
for(i;i<size;i++){
maps[s[i]]++;//使用查找表统计出所有字符出现的频次
}
int size2=t.size();
for(int j=0;j<size2;j++){
if(maps.find(t[j])!=maps.end())
maps[t[j]]--;
else{
return false;
}
}
//迭代器类型 容器类型 使用iter!=maps.end()
map<char,int>::iterator iter=maps.begin();
for(iter;iter!=maps.end();iter++){
if(iter->second!=0){
return false;
}
}
return true;
}
};时间复杂度为O(nlogn)
同样将map改变unordered_map hash表的实现方式,时间复杂度为O(n)

leetcode202: 判断一个数是否是happy number,难点如何通过查找表来实现无限循环的退出
class Solution {
public:
bool isHappy(int n) {
//使用一个map来存储每次计算的值,如果出现了重复那么就输出false
map<int,int> maps;
while(n!=1){
int sum=countSum(n);
if(sum==1){
return true;
}
maps.insert(pair<int,int>(n,sum));
if(maps.count(sum)){//返回1或者0;;
return false;
}
n=sum;

}
return true;
}
private:
int countSum(int n){
int sum=0;
while(n>0){
int temp=n%10;
sum+=temp*temp;
n=n/10;

}
return sum;}
};
leetcode290: 判断两个字符串是否匹配;难点如何构建相互之间的映射class Solution {
public:
bool wordPattern(string pattern, string str) {
//首先符字符串进行分词,然后构建相互的映射
vector<string> mystring=split(str);
map<char,string> mypatternMap;
map<string,char> mystringMap;
int i=0;
int size=pattern.size();
if(pattern.size()!=mystring.size()){
return false;
}
for(i;i<size;i++){
if(mypatternMap.find(pattern[i])==mypatternMap.end()&&mystringMap.find(mystring[i])==mystringMap.end()){
mypatternMap.insert(pair<char,string>(pattern[i],mystring[i]));
mystringMap.insert(pair<string,char>(mystring[i],pattern[i]));

}
else if(mypatternMap[pattern[i]]!=mystring[i]||mystringMap[mystring[i]]!=pattern[i]){
return false;
}
}
return true;
}
private:
vector<string> split(string str){
int i=0;
int size=str.size();
vector<string> ans;
int j=0;
for(i;i<size;i++){
if(str[i]==' '){
ans.push_back(str.substr(j,i-j));
j=i+1; }

if(i==size-1){
ans.push_back(str.substr(j,i-j+1));//包括当前元素
}
}
return ans;
}
};时间复杂度为O(nlog(n)),插入元素的时间复杂度为O(log(n))

同理leetcode205 也是相应的方式,通过构建hashTable,查看两个字符串是否是结构匹配;class Solution {
public:
bool isIsomorphic(string s, string t) {
if(s.size()!=t.size()){
return false;
}
map<char,char> charMap1;
map<char,char> charMap2;
for(int i=0;i<s.size();i++){
if(charMap1.find(s[i])==charMap1.end()&&charMap2.find(t[i])==charMap2.end()){
charMap1.insert(pair<char,char>(s[i],t[i]));
charMap2.insert(pair<char,char>(t[i],s[i]));
}
else if(charMap1[s[i]]!=t[i]||charMap2[t[i]]!=s[i]){
return false;
}
}
return true;
}
};时间复杂度为O(nlog(n))

接下来是leetcode451  Sort Characters By Frequency 按照字符出现的次数进行排序,返回排序后的字符串(核心就是如何对map中的值进行排序),使用数组,数组中的元素是pair类型的数据class Solution {
public:
string frequencySort(string s) {
//首先构建一个map来存储相应的hash结构,统计出现的频次
map<char,int> myMap;
int i=0;
int size=s.size();
for(i;i<size;i++){
myMap[s[i]]++;
}
//采用排序算法
// sort(myMap.begin(),myMap.end(),paixu);
// string ans="";
// map<char,int>::iterator iter=myMap.begin();
// for(iter;iter!=myMap.end();iter++){
// int j=0;
// while(j<iter->second){
// ans+=iter->first;
// j++;
// }
// }
// return ans; 以上算法不行 首先将pair元素push_back 到vector 中
vector<pair<char,int>> temp;
map<char,int>::iterator iter=myMap.begin();
for(iter;iter!=myMap.end();iter++){
temp.push_back(pair<char,int>(iter->first,iter->second));
}
sort(temp.begin(),temp.end(),paixu);
int size2=temp.size();
string ans="";
for(int i=0;i<size2;i++){
int j=0;
while(j<temp[i].second){
ans+=temp[i].first;
j++;
}
}
return ans;
}
private:
static int paixu( const pair<char,int>& map1, const pair<char,int>& map2){// 需要static 否则不能通过;
return map1.second>map2.second;
}
};

leetcode1 也可以用HashTable来实现,时间复杂大大降低class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
//使用hashtable
int i=0;
int size=nums.size();
map<int,int> myMap;
vector<int> result;
for(i;i<size;i++){
if(myMap.find(nums[i])!=myMap.end()){//如果有重复的元素出现
if(nums[i]==target-nums[i]){
result.push_back(myMap.find(nums[i])->second);
result.push_back(i);
return result;
}
}
myMap[nums[i]]=i;//

}

map<int,int>::iterator iter=myMap.begin();
for(iter;iter!=myMap.end();iter++){
if(myMap.find(target-iter->first)!=myMap.end()){
map<int,int>::iterator iter2=myMap.find(target-iter->first);
result.push_back(iter->second);
result.push_back(iter2->second);
return result;
}
}

return result;
}
};时间复杂度为O(nlogn),空间复杂度为O(n),运行时间13ms
如果将map换成unordered_map输出错误的结果?? 有谁知道为什么吗?
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: