leetcode刷题笔记_哈希表2

哈希表2

早上刚好连续几题都是beat100%碰巧云顶之奕又更新了,想着打两把放松一下,结果打了一下午愣是没赢过,晚上刷leetcode,最后一题愣是没写出来,心态有点小崩

实际应用

字母异位词分组

给定一个字符串数组,将字母异位词组合在一起。可以按任意顺序返回结果列表。

字母异位词指字母相同,但排列不同的字符串。

class Solution {
public:
    vector> groupAnagrams(vector& strs) {
       
        map> mp;
        for(auto str:strs)//遍历字符串数组
        {        
            string Oristr=str; //记录原始字符串
            sort(str.begin(),str.end());//对字符串进行排序
            mp[str].push_back(Oristr); //把原字符串加到异位词的键对应的数组后面

        }
        //遍历每个异位词对应的数组,加到结果数组里
        vector> res;
        map>::iterator it;
        it=mp.begin();
        while(it!=mp.end())
        {
            res.push_back(it->second);
            it++;
        }
        return res;



    }
};

移位字符串分组

给定一个字符串,对该字符串可以进行 “移位” 的操作,也就是将字符串中每个字母都变为其在字母表中后续的字母,比如:“abc” -> “bcd”。这样,我们可以持续进行 “移位” 操作,从而生成如下移位序列:

“abc” -> “bcd” -> … -> “xyz”
给定一个包含仅小写字母字符串的列表,将该列表中所有满足 “移位” 操作规律的组合进行分组并返回

作者:力扣 (LeetCode)
链接:https://leetcode-cn.com/leetbook/read/hash-table-plus/x7deic/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

class Solution {
public:
    vector> groupStrings(vector& strings) {
        
      
        map> mp;
        for(int i=0;i> res;
        map>::iterator it;
        it=mp.begin();
        while(it!=mp.end())
        {
            res.push_back(it->second);
            it++;
        }
        return res;

    }
};

有效的数独

请你判断一个 9x9 的数独是否有效。只需要 根据以下规则 ,验证已经填入的数字是否有效即可。

数字 1-9 在每一行只能出现一次。
数字 1-9 在每一列只能出现一次。
数字 1-9 在每一个以粗实线分隔的 3x3 宫内只能出现一次。(请参考示例图)
数独部分空格内已填入了数字,空白格用 ‘.’ 表示。

注意:

一个有效的数独(部分已被填充)不一定是可解的。
只需要根据以上规则,验证已经填入的数字是否有效即可。

作者:力扣 (LeetCode)
链接:https://leetcode-cn.com/leetbook/read/hash-table-plus/x70xli/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

class Solution {
public:
    bool isValidSudoku(vector>& board) {
        //定义三个哈希表记录行列和九宫格里有没有重复的
        map line[9],row[9],box[9];
       for(int i=0;i<9;i++)
       {
           for(int j=0;j<9;j++)
           {
               //是空格就继续下一个
               if(board[i][j]=='.')
                    continue;
               //数字有重复返回false,i/3*3+j表示第几个九宫格
               if(line[i].count(board[i][j])!=0||row[j].count(board[i][j])!=0||box[i/3*3+j/3].count(board[i][j])!=0)
                    return false;
                //如果不是空格且未出现过就更新哈希表,把当前值加进去
                    line[i][board[i][j]]++;
                    row[j][board[i][j]]++;
                    box[i/3*3+j/3][board[i][j]]++;
                
                
               
           }
       }
       return true;

    }
};

寻找重复的子树

给定一棵二叉树,返回所有重复的子树。对于同一类的重复子树,你只需要返回其中任意一棵的根结点即可。

两棵树重复是指它们具有相同的结构以及相同的结点值。

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
public:
    vector res;
    map mp;
    
    vector findDuplicateSubtrees(TreeNode* root) {
        dfs(root);
        return res;
    }
    string dfs(TreeNode* root)
    {
        if(root==nullptr)
            return "";
        //把一个结点本身和他的左右子树一起存到字符串里
        //为了区分2,3,3和233,null,null用逗号分隔根节点和左右孩子
        string val=to_string(root->val)+","+dfs(root->left)+","+dfs(root->right);
        //如果这棵子树已经在哈希表里出现过那就直接把根结点加到结果
        if(mp[val]==1)
            res.push_back(root);
        //否则把当前结点添加进哈希表
        mp[val]++;
        return val;
    }
};

稀疏矩阵的乘法

class Solution {
public:
    vector> multiply(vector>& mat1, vector>& mat2) {
        
        int line=mat1.size();
        int row=mat2[0].size();
        vector> res(line,vector(row,0));
        if(line==0||row==0)
            return {};
        for(int i=0;i

小结与讨论

宝石与石头

给定字符串J 代表石头中宝石的类型,和字符串 S代表你拥有的石头。 S 中每个字符代表了一种你拥有的石头的类型,你想知道你拥有的石头中有多少是宝石。

J 中的字母不重复,J 和 S中的所有字符都是字母。字母区分大小写,因此"a"和"A"是不同类型的石头。

作者:力扣 (LeetCode)
链接:https://leetcode-cn.com/leetbook/read/hash-table/xx2a0c/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

class Solution {
public:
    int numJewelsInStones(string jewels, string stones) {
        //其实就是判断第二个字符串是不是在第一个字符串里,如果是就+1
        int res=0;
        //用哈希表存储第一个字符串出现的字符
        map jewel;
        for(auto val:jewels)
            jewel[val]++;
        //遍历第二个字符串的字符,如果在哈希表里,说明出现在了第一个字符串中,说明时宝石res+1
        for(auto val:stones)
        {
            if(jewel.count(val)!=0)
                res++;
        }
        return res;

    }
};

无重复字符的最长子串

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

class Solution {
public:
    int lengthOfLongestSubstring(string s) {
        if(s.size()<=1)
            return s.size();     
        //哈希表统计有没有重复
        map mp;
        int left=0,right=0,len=0;
        while(right!=s.size())
        {
            
            //重复了就滑动窗口,左指针移到重复位置的下一位或者当前位置(重复位置不在区间内相当于不移动)
            if(mp.count(s[right])!=0)
            {
                left=max(mp[s[right]]+1,left);
            }
            //不重复就更新子串长度,并在哈希表中记录当前字符的位置
            
                len=max(len,right-left+1);
                mp[s[right]]=right;
            
            //不重复就继续右移,同时更新最大值
            right++;        
        }
        return len;
    }
};

两数之和 III - 数据结构设计

设计一个接收整数流的数据结构,该数据结构支持检查是否存在两数之和等于特定值。

实现 TwoSum 类:

TwoSum() 使用空数组初始化 TwoSum 对象
void add(int number) 向数据结构添加一个数 number
boolean find(int value) 寻找数据结构中是否存在一对整数,使得两数之和与给定的值相等。如果存在,返回 true ;否则,返回 false 。

作者:力扣 (LeetCode)
链接:https://leetcode-cn.com/leetbook/read/hash-table/xxv9we/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

class TwoSum 
{
public:
    map mp;

    /** Initialize your data structure here. */
    TwoSum() 
    {

    }
    
    /** Add the number to an internal data structure.. */
    void add(int number) 
    {
        if (mp.count(number) != 0)
            mp[number] ++;
        else
            mp[number] = 1;
    }
    
    /** Find if there exists any pair of numbers which sum is equal to the value. */
    bool find(int value) 
    {
        for (auto [x, freq]: mp)
        {
          
            if (x == value - x)
            {
                if (mp[x] >= 2)
                    return true;
            }
            else
            {
                if (mp.count(value - x) != 0)
                {
                    return true;
                }
            }
        }
        return false;
    }
};

四数相加 II

给定四个包含整数的数组列表 A , B , C , D ,计算有多少个元组 (i, j, k, l) ,使得 A[i] + B[j] + C[k] + D[l] = 0。

为了使问题简单化,所有的 A, B, C, D 具有相同的长度 N,且 0 ≤ N ≤ 500 。所有整数的范围在 -228 到 228 - 1 之间,最终结果不会超过 231 - 1 。

作者:力扣 (LeetCode)
链接:https://leetcode-cn.com/leetbook/read/hash-table/xxwhng/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

class Solution {
public:
    int fourSumCount(vector& nums1, vector& nums2, vector& nums3, vector& nums4) {
        //a+b+c+d=0  a+b=-(c+d)
        int res=0;
        int len=nums2.size();
        //把a+b的和放进哈希表里
        map mp;
        
        for(int i=0;i0)
                    res=res+mp[-nums3[i]-nums4[j]];
            }
        }
        return res;

    }
};

单词的唯一缩写

单词的 缩写 需要遵循 <起始字母><中间字母数><结尾字母> 这样的格式。如果单词只有两个字符,那么它就是它自身的 缩写 。

以下是一些单词缩写的范例:

dog --> d1g 因为第一个字母 ‘d’ 和最后一个字母 ‘g’ 之间有 1 个字母
internationalization --> i18n 因为第一个字母 ‘i’ 和最后一个字母 ‘n’ 之间有 18 个字母
it --> it 单词只有两个字符,它就是它自身的 缩写

实现 ValidWordAbbr 类:

ValidWordAbbr(String[] dictionary) 使用单词字典 dictionary 初始化对象
boolean isUnique(string word) 如果满足下述任意一个条件,返回 true ;否则,返回 false :
字典 dictionary 中没有任何其他单词的 缩写 与该单词 word 的 缩写 相同。
字典 dictionary 中的所有 缩写 与该单词 word 的 缩写 相同的单词都与 word 相同 。

作者:力扣 (LeetCode)
链接:https://leetcode-cn.com/leetbook/read/hash-table/xxd1mj/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

class ValidWordAbbr {
public:
    //把缩写作为键存在哈希表里,对应字典上的单词
    map> mmp;
    ValidWordAbbr(vector& dictionary) {
        for(auto str:dictionary)
        {
            string key;
            if(str.size()<=2)
                key=str;
            else
                key=str[0]+to_string(str.size()-2)+str[str.size()-1];
            mmp[key].push_back(str);
        }
            

    }
    //如果在哈希表里找不到返回true
    //如果找到了并且word和对应的键的都相同返回true
    //有一个不同就返回false
    bool isUnique(string word) {
        string key;
        if(word.size()<=2)
            key=word;
        else
            key=word[0]+to_string(word.size()-2)+word[word.size()-1];
        if(mmp.find(key)==mmp.end())
            return true;
        for(auto val:mmp[key])
            if(val!=word)
                return false;
        return true;
        

    }
};

/**
 * Your ValidWordAbbr object will be instantiated and called as such:
 * ValidWordAbbr* obj = new ValidWordAbbr(dictionary);
 * bool param_1 = obj->isUnique(word);
 */

你可能感兴趣的:(leetcode,数据结构)