算法-哈希表
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); } };