leetcde 查找表问题

查找表相关问题总结

一、查找表分类

查找问题一般分为两类查找问题

  • 查找有无  使用set,里面没有重复的键,唯一,即只有键,没有键值
  • 查找对应关系(键值对应)  使用map

c++语言中,map与set底层实现为平衡二叉树;而unorder_set与unorder_map底层实现为哈希表,因此也就失去了数据的顺序性。
###二、常见的操作

  • insert
  • find
  • erase
  • change(一般多用在map这种数据结构中)

需要注意的是在各个程序语言特性中其实现机制不一样

/**
 * 349.求两个数组的交集
 * 每个元素是唯一的
 * */
class Solution1 {
public:
    vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {
        set<int>myset(nums1.begin(),nums1.end());
        //vector<int> result;
        set<int>resultset;
        for(int i = 0; i < nums2.size(); i++){
            if(myset.find(nums2[i]) != myset.end())
                resultset.insert(nums2[i]);
        }
        return vector<int>(resultset.begin(),resultset.end());
    }
};

/**此题是不是有问题
 * 350.两个数组的交集
 * 输出结果中每个元素出现的次数,应与元素在两个数组中出现的次数一致!!!!!此处是不是有错误
 * 我们可以不考虑输出结果的顺序
 * 输入: nums1 = [4,9,5], nums2 = [9,4,9,8,4]输出: [4,9]
 * */
class Solution{
public:
    vector<int> intersect(vector<int>& nums1, vector<int>& nums2) {
        map<int,int>mymap;
        vector<int>result;
        for(auto c:nums1)
            mymap[c]++;
        for(int i = 0; i< nums2.size(); i++){
            if(mymap[nums2[i]]>0 ) {
                result.push_back(nums2[i]);
                mymap[nums2[i]]--;
            }
        }

        return  result;
    }
};

/**
 * 242.有效的字母异位词
 *
 * */
class Solution3 {
public:
//    bool isAnagram(string s, string t) {
//        if(s.size() != t.size())
//            return false;
//        if(s.empty())//忘记了空集
//            return true;
//
//        unordered_map<char ,int >mymap;
//        unordered_map<char ,int >mymap2;
//        for(auto c : s)
//            mymap[c]++;
//        for(auto c : t)
//            mymap2[c]++;
//        unordered_map<char,int>::iterator iter;
//        int count = 0;
//        for(iter = mymap.begin();iter != mymap.end(); iter++)
//            if(mymap2[iter->first] == iter ->second)
//                count++;
//        if(count == mymap.size())//之前此处代码逻辑出错了
//            return true;
//        else
//            return false;
//    }
    //此处代码进行了优化
    bool isAnagram(string s, string t) {
        if(s.size() != t.size())
            return false;
        if(s.empty())//忘记了空集
            return true;

        unordered_map<char ,int >mymap;
        unordered_map<char ,int >mymap2;
        for(int i = 0; i < s.size(); i++)
        {
            mymap[s[i]]++;
            mymap2[t[i]]++;
        }
        unordered_map<char,int>::iterator iter;
        int count = 0;
        for(iter = mymap.begin();iter != mymap.end(); iter++)
            if(mymap2[iter->first] != iter ->second)
                return false;//只要不满足就返回false
        return true;

    }
};

/**
 * 202.快乐数
 * */
class Solution4 {
public:
    bool isHappy(int n) {
        assert(n > 0);
        int temp = n;
        set<int> myset;
        while (n != 1) {
            int sum = 0;
            while (n > 0) {
                sum += (n % 10) * (n % 10);
                n /= 10;}
            if (myset.find(sum) == myset.end())//如果没有找到,则将其进行插入
                myset.insert(sum);
            else {//如果找到了,说明存在循环,则不是幸福数
                return false;
            }
            n = sum;
        }
        return true;
    }
};

/**
 * 290 单词模式
 * 利用两个哈希表的键值对应来做
 * */
class Solution5 {
public:
    bool wordPattern(string pattern, string str) {
//        map<string,int>mymap1;
//        map<char,int>mymap2;
        unordered_map<string, char> mymap1;
        unordered_map<char, string> mymap2;
        vector<string> strVector;
        str.push_back(' ');//补个空格便于分割
        int index = 0;
        for (int i = 0; i < str.size(); ++i) {
            if (str[i] != ' ')
                index++;
            else {
                strVector.push_back(str.substr(i - index, index));
                index = 0;
            }
        }
        if (pattern.size() != strVector.size())
            return false;
        for (int i = 0; i < pattern.size(); i++) {
            if (mymap2.find(pattern[i]) == mymap2.end() && mymap1.find(strVector[i]) == mymap1.end()) {
                mymap2[pattern[i]] = strVector[i];
                mymap1[strVector[i]] = pattern[i];
            } else if (mymap1[strVector[i]] != pattern[i]) {//如果键值不等或者该键值不存在(此时也不等于)
                return false;
            }
        }

        return true;
    }
};
/**
 * 205. 同构字符串
 * */
class Solution6 {
public:
    bool isIsomorphic(string s, string t) {
        unordered_map<char, char> mymap1;//此处换成哈希表非常的快
        unordered_map<char, char> mymap2;

        if (s.size() != t.size())
            return false;
        for (int i = 0; i < s.size(); i++) {
            if (mymap2.find(s[i]) == mymap2.end() && mymap1.find(t[i]) == mymap1.end()) {
                mymap2[s[i]] = t[i];
                mymap1[t[i]] = s[i];
            } else if (mymap1[t[i]] != s[i]) {//如果键值不等或者该键值不存在(此时也不等于)
                return false;
            }
        }

        return true;
    }

};

/*相关的解决思路,速度非常快, string可以直接查找
class Solution {
public:
    bool isIsomorphic(string s, string t) {
        if(s.length()==0)return true;

        int i=0;

        while(i<s.length())
        {
            if(s.find(s[i])!=t.find(t[i]))
                return false;
            i++;
        }
        return true;

    }
};*/


/**
 * 451.根据字符出现频率排序
 * 给定一个字符串,请将字符串里的字符按照出现的频率降序排列。
 * */
 //自己写的写错了
class Solution {
public:
    string frequencySort(string s) {
        unordered_map<char, int> mymap1;
        map<int, char> mymap2;
        for( auto c : s){
            mymap1[c]++;
        }
        unordered_map<char ,int>::iterator iter;
        for( iter = mymap1.begin(); iter != mymap1.end(); iter++){
            mymap2[iter->second] = iter -> first;
        }
        string result;
        map<int ,char>::iterator iter2;
        for( iter2 = mymap2.begin(); iter2 != mymap2.end(); iter2++){
           for( int i = 0; i < iter ->first; i ++ )
               result.push_back(iter->second);
        }
        return result;

    }

};
/*利用了pair
 *  string frequencySort(string s) {
        string res = "";
        unordered_map<char, int> myMap;
        vector<pair<char, int>> myVec;
        //统计所有的字母出现的频次
        for (int i = 0; i < s.size(); i++) {
            myMap[s[i]]++;
        }
        //将字母及频次存入Vector,便于之后的排序
        for (auto it = myMap.begin(); it != myMap.end(); it++) {
            myVec.push_back(make_pair(it->first, it->second));
        }
        //按照字母出现的频次从大到小进行排序
        sort(myVec.begin(), myVec.end(), [](const pair<char, int>& x, const pair<char, int>& y) -> int {
            return x.second > y.second;//labmda表达式
        });
        //将排序后的字母,根据其频次,依次添加对应数量的该字母进入结果字符串中
        for (auto it = myVec.begin(); it != myVec.end(); it++) {
            for (int i = 0; i < it->second; i++) {
                res += it->first;
            }
        }
        return res;
    }
 * */

还有一个典型的查找表问题,就是leetcode当中的k-sum 问题

猜你喜欢

转载自blog.csdn.net/qq_40028201/article/details/89452104