数据结构与算法4-哈希表

数据结构与算法-字符串与哈希表

往期内容
1-链表
2-栈与队列
3-树与图
4-哈希表
5-查找
6-排序
7-贪心
8-递归与分治
9-动态规划




1.最长回文串

Leetcode-409 最长回文串
思路:利用一个数组,记录所有的字符的个数,如果该位置的个数是偶数个,全部记录下来,如果是奇数个,减1在全部记录下来,并定义一个flag保存中心奇数点。

class Solution {
public:
    int longestPalindrome(string s) {
        int char_map[128]={0};
        int max_length=0;
        int flag=0;

        for(int i=0;i<s.size();i++)
        {
            char_map[s[i]]++;
        }

        for(int i=0;i<128;i++)
        {
            if(char_map[i]%2==0)
            {
                max_length+=char_map[i];
            }
            else
            {
                if(!flag)
                {
                    flag=1;
                }
                max_length=max_length+(char_map[i]-1);

            }
        }
        return max_length+flag;
    }
};

2.单词规律

Leetcode-290 单词规律
思路:利用一个数组统计,模式串中的每个字符是否出现过,利用一个map记录字符串和对于模式的关系,当找到一个新的字符串的时候:查找它是否在map中,检查是否完全匹配,当它不在时,检查与之对应的value是否已经出现在数组中,如果在,表示之前有值与之匹配,返回false,否则将键值插入到map集合中。

class Solution {
public:
    bool wordPattern(string pattern, string s) {
        //map的映射  string->char
        map<string,char> word_map;
        char used[128]={0};
        string word;
        int pos=0;
        s.push_back(' ');//尾部添加一个空格,方便处理
        for(int i=0;i<s.size();i++)
        {
            if(s[i]==' ')//表示拆分到了一个单词
            {
                if(pos==pattern.size())//1.查到尾部,s长 pattern短
                    return false;
                if(word_map.find(word)==word_map.end())//单词不在哈希映射中
                {
                    if(used[pattern[pos]]==1){
                       return false; 
                    }
                    word_map[word]=pattern[pos];
                    used[pattern[pos]]=1;
                }
                else
                {
                    if(word_map[word]!=pattern[pos])
                    {
                        return false;
                    }
                }

                word="";
                pos++;
                
            }
            else
            {
                word+=s[i];
            }
        }
        if(pos!=pattern.size())//pattern长,s短
        {
            return false;
        }

        return true;

    }
};

3.字母异位词分组

Leetcode-49 字母异位词分组
思路1:排序

class Solution {
public:
    vector<vector<string>> groupAnagrams(vector<string>& strs) {
        vector<vector<string>> result;
        map<string,vector<string>> anagrams;

        for(int i=0;i<strs.size();i++)
        {
            string s=strs[i];
            sort(s.begin(),s.end());

            if(anagrams.find(s)==anagrams.end())
            {
                vector<string> temp_s;
                anagrams[s]=temp_s;
            }
            anagrams[s].push_back(strs[i]);
        }

        for(map<string,vector<string>>::iterator it=anagrams.begin();it!=anagrams.end();it++)
        {
            result.push_back((*it).second);
        }
        return result;
        

    }
};

思路2:vector容器记录所有的位置和每个位置出现的次数

class Solution {
public:
    void change_to_vector(string & str,vector<int> &vec)
    {
        for(int i=0;i<26;i++)
        {
            vec.push_back(0);
        }
        for(int i=0;i<str.size();i++)
        {
            vec[str[i]-'a']++;
        }
    }
    vector<vector<string>> groupAnagrams(vector<string>& strs) {
        map<vector<int>,vector<string>> anagrans;
        vector<vector<string>> result;

        for(int i=0;i<strs.size();i++)
        {
            vector<int> vec;
            change_to_vector(strs[i],vec);
            if(anagrans.find(vec)==anagrans.end())
            {
                vector<string> item;
                anagrans[vec]=item;
            }
            anagrans[vec].push_back(strs[i]);
        }

        for(map<vector<int>,vector<string>>::iterator it=anagrans.begin();it!=anagrans.end();it++)
        {
            result.push_back((*it).second);
        }

        return result;
    }
};

4.无重复字符的最长子串-重要

Leetcode-3 无重复字符的最长子串
思路:窗口思想,用begin和i维护一个窗口的大小

class Solution {
public:
    int lengthOfLongestSubstring(string s) {
        //窗口的思想
        //双指针-快指针遇到字符会被添加到集合中,慢指针遇到字符
        //将会从哈希集合中删除
        int begin=0;
        int result=0;
        string word="";
        int char_map[128]={0};

        for(int i=0;i<s.size();i++)
        {
            char_map[s[i]]++;
            if(char_map[s[i]]==1)//没有出现过该字符
            {
               word+=s[i];

               if(result<word.length())
                    result=word.length();
            }
            else//删除重复s[i]
            {
                while(begin<i && char_map[s[i]]>1){
                    char_map[s[begin]]--;
                    begin++;
                }
                word="";
                for(int j=begin;j<=i;j++)
                    word+=s[j];

            }
        }

        return result;
    }
};

5.重复的DNA序列

Leetcode-187 重复的DNA序列
思路:map:建子串,值出现的次数,如果改子串在map中,值加1,否则将改子串插入到map中,最后遍历整个map得出结果

class Solution {
public:
    vector<string> findRepeatedDnaSequences(string s) {
        map<string,int> word_map;
        vector<string> result;

        if(s.size()<10) return {};

        for(int i=0;i<s.size()-9;i++)
        {
            string word=s.substr(i,10);
            if(word_map.find(word)!=word_map.end())
            {
                word_map[word]+=1;
            }
            else
            {
                word_map[word]=1;
            }
        }


        for(map<string,int>::iterator it=word_map.begin();it!=word_map.end();it++)
        {
            if(it->second>1)
                result.push_back(it->first);
        }
        return result;
    }
};

6.最小覆盖子串

Leetcode-76 最小覆盖子串

class Solution {
public:
    //检测是否包含所有字符
    bool is_baohan_char(int map_s[],int map_t[],vector<int> &vec)//检查窗口是否包含所有的字符
    {                                                         //map_s记录窗口s串中各个字符的个数 
        for(int i=0;i<vec.size();i++)
        {
            if(map_s[vec[i]]<map_t[vec[i]])
                return false;
        }
        return true;
    }
    
    string minWindow(string s, string t) {
        const int MAX_ARRAY_LEN=128;
        int map_t[MAX_ARRAY_LEN]={0};
        int map_s[MAX_ARRAY_LEN]={0};

        vector<int> vect;

        for(int i=0;i<t.size();i++)
        {
            map_t[t[i]]++;
        }
        for(int i=0;i<MAX_ARRAY_LEN;i++)
        {
            if(map_t[i]>0)
            {
                vect.push_back(i);
            }
        }
        int window_begin=0;
        string result;

        for(int i=0;i<s.size();i++)
        {
            map_s[s[i]]++;

            while(window_begin<i)//有重复元素
            {
                char begin_char=s[window_begin];
                if(map_t[begin_char]==0)
                {
                    window_begin++;
                }
                else if(map_s[begin_char]>map_t[begin_char])
                {
                    map_s[begin_char]--;
                    window_begin++;
                }
                else
                {
                    break;
                }

            }

            if(is_baohan_char(map_s,map_t,vect))
            {
                int new_window_len=i-window_begin+1;
                if(result=="" || result.size()>new_window_len)
                {
                    result=s.substr(window_begin,new_window_len);
                }
            }
        }

        return result;

        
    }
};

7.有效的字母异位词

Leetcode-242 有效的字母异位词
方法1:排序
方法2:哈希表,用数组记录字符的位置

class Solution {
public:
    bool isAnagram(string s, string t) {
        //方法2:字母表
        if(s.size()!=t.size()) return false;

        vector<int> s_vec(26,0);
        vector<int> t_vec(26,0);


        for(int i=0;i<s.size();i++)
        {
            s_vec[s[i]-'a']++;
            t_vec[t[i]-'a']++;
        }
        for(int i=0;i<26;i++)
        {
            if(s_vec[i]!=t_vec[i])
                return false;
        }
        return true;
    }
};

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值