算法-哈希表

1.给定一个包含大写字母和小写字母的字符串,找到通过这些字母构造成的最长的回文串。

在构造过程中,请注意区分大小写。比如 "Aa" 不能当做一个回文字符串。

注意:
假设字符串的长度不会超过 1010。

示例 1:

输入:
"abccccdd"

输出:
7

解释:
我们可以构造的最长的回文串是"dccaccd", 它的长度是 7。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/longest-palindrome
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

class Solution {
public:
    int longestPalindrome(string s) {
        map<char,int> nums;
        for(int i=0;i<s.size();++i){
            nums[s[i]]++;
        }
        int count=0;
        bool hasSingleChar=false;
        for(auto c:nums){
            if(c.second % 2 ==0) count+=c.second;
            else{ 
                hasSingleChar=true;
                count+=c.second-1;;
            }
        }
        count+=hasSingleChar;
        return count;
    }
};
class Solution {
public:
    int longestPalindrome(string s) 
    {
        int n=s.length();
        unordered_map<char,int> tmp;
        for(int i=0;i<n;i++)
        {
            tmp[s[i]]++;
        }
        unordered_map<char,int>::iterator it;
        for(it=tmp.begin();it!=tmp.end();it++)
        {
            if(it->second%2==1)
            {
                n--;
            }
        }
        if(n==s.length())
        {
            return n;
        }
        else
        {
            return n+1;
        }
    }
};

2.给定一种规律 pattern 和一个字符串 str ,判断 str 是否遵循相同的规律。

这里的 遵循 指完全匹配,例如, pattern 里的每个字母和字符串 str 中的每个非空单词之间存在着双向连接的对应规律。

示例1:

输入: pattern = "abba", str = "dog cat cat dog"
输出: true

示例 2:

输入:pattern = "abba", str = "dog cat cat fish"
输出: false

示例 3:

输入: pattern = "aaaa", str = "dog cat cat dog"
输出: false

示例 4:

输入: pattern = "abba", str = "dog dog dog dog"
输出: false

说明:
你可以假设 pattern 只包含小写字母, str 包含了由单个空格分隔的小写字母。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/word-pattern
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

vector<string> split(string str){
    str.push_back(' ');//加个空格,避免处理边界条件!!!
    vector<string> strs;
    string s="";
    for(int i=0;i<str.size();++i){
         if(str[i]!=' ') s+=str[i];
         else {
             strs.push_back(s);
             s="";
         }
     }
    return strs;
 }
class Solution {
public:
    bool wordPattern(string pattern, string str) {
        vector<string> strs=split(str);
        if(strs.size()!=pattern.size()) return false;
        unordered_map<string,char> str_to_char_map;//两个哈希表,形成映射
        unordered_map<char,string> char_to_str_map;
        for(int i=0;i<strs.size();++i){
            if(str_to_char_map.find(strs[i])!=str_to_char_map.end()){
                if(str_to_char_map[strs[i]]==pattern[i])
                    continue;
                else return false;
            }else{                
                if(char_to_str_map.find(pattern[i])==char_to_str_map.end()){
                    str_to_char_map[strs[i]]=pattern[i];
                    char_to_str_map[pattern[i]]=strs[i];
                }else{
                    if(char_to_str_map[pattern[i]]!=strs[i]) return false;
                }
            }
        }
        return true;
    }
};
vector<string> split(string str){
    str.push_back(' ');//加个空格,避免处理边界条件!!!
    vector<string> strs;
    string s="";
    for(int i=0;i<str.size();++i){
         if(str[i]!=' ') s+=str[i];
         else {
             strs.push_back(s);
             s="";
         }
     }
    return strs;
 }
class Solution {
public:
    bool wordPattern(string pattern, string str) {
        vector<string> strs=split(str);
        if(strs.size()!=pattern.size()) return false;
        unordered_map<string,char> str_to_char_map;//两个哈希表,形成映射
        char used[128]={0};//检测字母是否已经映射过
        for(int i=0;i<strs.size();++i){
            if(str_to_char_map.find(strs[i])!=str_to_char_map.end()){
                if(str_to_char_map[strs[i]]==pattern[i])
                    continue;
                else return false;
            }else{                
                if(used[pattern[i]]) return false;
                else {
                    str_to_char_map[strs[i]]=pattern[i];
                    used[pattern[i]]=1;
                }
            }
        }
        return true;
    }
};

3.给定一个字符串数组,将字母异位词组合在一起。字母异位词指字母相同,但排列不同的字符串。

示例:

输入: ["eat", "tea", "tan", "ate", "nat", "bat"],
输出:
[
  ["ate","eat","tea"],
  ["nat","tan"],
  ["bat"]
]

说明:

    所有输入均为小写字母。
    不考虑答案输出的顺序。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/group-anagrams
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

/*排序字符串相同的映射到一个key下,key为已排序的字符串*/
class Solution {
public:
    vector<vector<string>> groupAnagrams(vector<string>& strs) {
        
        int len=strs.size();
        vector<vector<string>> res;
        unordered_map<string,vector<string>> map;
        string temp;
        for(int i=0;i<len;++i){
            temp=strs[i];
            sort(temp.begin(),temp.end());//字符串排序得到key值
            if(map.find(temp)==map.end()){
                vector<string> item;/*如果表中没有,则创建vector,加到表中*/
                map[temp]=item;
            }
            map[temp].push_back(strs[i]); /*加到key下的vector*/     
        }
        unordered_map<string,vector<string>>::iterator it;
        for(it=map.begin();it!=map.end();it++){
            res.push_back((*it).second);
        }
        return res;
    }
};
vector<int> numsOfEveryChar(string str){
    vector<int> nums;
    for(int i=0;i<26;++i){
        nums.push_back(0);
    }
    for(int i=0;i<str.length();++i){
        nums[str[i]-'a']++;
    }
    return nums;
}
class Solution {
public:
    vector<vector<string>> groupAnagrams(vector<string>& strs) {
        
        int len=strs.size();
        vector<vector<string>> res;
        map<vector<int>,vector<string>> m;
        vector<int> num;
        for(int i=0;i<len;++i){
            num=numsOfEveryChar(strs[i]);
            if(m.find(num)==m.end()){
                vector<string> list;                
                m[num]=list;
            }
            m[num].push_back(strs[i]);
        }
        map<vector<int>,vector<string>>::iterator it;
        for(it=m.begin();it!=m.end();it++){
            res.push_back((*it).second);
        }
        return res;
    }
};

4.给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度。

示例 1:

输入: "abcabcbb"
输出: 3
解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。

示例 2:

输入: "bbbbb"
输出: 1
解释: 因为无重复字符的最长子串是 "b",所以其长度为 1。

示例 3:

输入: "pwwkew"
输出: 3
解释: 因为无重复字符的最长子串是 "wke",所以其长度为 3。
     请注意,你的答案必须是 子串 的长度,"pwke" 是一个子序列,不是子串。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/longest-substring-without-repeating-characters
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

class Solution {
public:
    int lengthOfLongestSubstring(string s) {
        int n=s.size(),res=0;
        int index[128]={0};
        for(int j=0,i=0;j<n;j++){
            i=max(index[  s[j]  ],i);//刷新开始点,为当前遇到字符的前面所存储的索引后一个索引
            res=max(res,j-i+1);//更新结果
            index[   s[j]   ]=j+1;//index指向该字符索引的后面一个索引
        }
        return res;  
    }
};

5.所有 DNA 由一系列缩写为 A,C,G 和 T 的核苷酸组成,例如:“ACGAATTCCG”。在研究 DNA 时,识别 DNA 中的重复序列有时会对研究非常有帮助。

编写一个函数来查找 DNA 分子中所有出现超多一次的10个字母长的序列(子串)。

示例:

输入: s = "AAAAACCCCCAAAAACCCCCCAAAAAGGGTTT"

输出: ["AAAAACCCCC", "CCCCCAAAAA"]

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/repeated-dna-sequences
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

class Solution {
public:
    vector<string> findRepeatedDnaSequences(string s) {
        unordered_map<string,int> m;
        vector<string> res;
        string temp;
        for(int i=0;i<s.size();++i){
            temp=s.substr(i,10);
            if(m.find(temp)==m.end()){
                m[temp]=1;
            }else{
                m[temp]++; 
            }
                       
        }
        unordered_map<string,int>::iterator it;
        for(it=m.begin();it!=m.end();++it){
            if(it->second>1) res.push_back(it->first);  
        }
        return res;
    }
};

6.给你一个字符串 S、一个字符串 T,请在字符串 S 里面找出:包含 T 所有字母的最小子串。

示例:

输入: S = "ADOBECODEBANC", T = "ABC"
输出: "BANC"

说明:

    如果 S 中不存这样的子串,则返回空字符串 ""。
    如果 S 中存在这样的子串,我们保证它是唯一的答案。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/minimum-window-substring
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

unordered_map<char,int> charnums(string t){
    unordered_map<char,int> nums;
    for(int c=0;c<128;c++){
        nums[c]=0;
    }
    for(int i=0;i<t.size();++i){
        nums[t[i]]++;
    }
    return nums;
}
class Solution {
public:
    string minWindow(string s, string t) {
        int n=s.size(),left=0,right=0,res=s.size(),count=0,resleft=0;
        unordered_map<char,int> charCountOfT=charnums(t);
        unordered_map<char,int> charCountOfS;
        for(int i=0;i<n;++i){
            if(t.find(s[i])!=-1){
                if(charCountOfS.find(s[i])==charCountOfS.end()){
                    charCountOfS[s[i]]=1;
                    count++;                   
                }else{
                    charCountOfS[s[i]]++;
                    if(charCountOfS[s[i]]<=charCountOfT[s[i]]){
                        count++;
                    }
                }
                 
                //达到包含所有字符后缩减窗口大小
                if(count==t.size()){
                    right=i;
                    while(left<=right){
                        if(t.find(s[left])==-1){
                            left++;                            
                        }else{
                            if(charCountOfS[s[left]]>charCountOfT[s[left]]){ 
                                charCountOfS[s[left]]--;
                                left++;
                            }else{
                                if(right-left<res) {
                                    res=right-left;
                                    resleft=left;
                                }                                    
                                break;
                            }
                        }
                    }
                }      
            }  
        }
        if(count<t.size()) return "";
        return s.substr(resleft,res+1);
    }
};
原文地址:https://www.cnblogs.com/chendaniu/p/10199500.html