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

之前都是数组的操作,接下来介绍的数据结构是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输出错误的结果?? 有谁知道为什么吗?

猜你喜欢

转载自blog.csdn.net/hufanglei007/article/details/79455887
007