leetcode 哈希表相关算法刷题笔记

2022/1/6 20:04:57

本文主要是介绍leetcode 哈希表相关算法刷题笔记,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

刷题笔记

  • hash table 算法leetcode专栏
      • leetcode 242 有效的字母异位词
      • leetcode 383 赎金信
      • leetcode 49 字母异位词分组
      • leetcode 138 复制带随机指针的链表
      • leetcode 1002 查找共用字符
      • leetcode 349 两个数组的交集
      • leetcode 350 两个数组的交集II
      • leetcode 202 快乐数
      • leetcode 1 两数之和
      • leetcode 15 三数之和
      • leetcode 18 四数之和
      • leetcode 454 四数相加II

hash table 算法leetcode专栏

leetcode 242 有效的字母异位词

class Solution {
public:
    bool isAnagram(string s, string t) {
        vector<int> hashVec(26, 0);
        for(int i = 0; i < s.size(); i++)
        {
            hashVec[s[i] -'a']++;
        }
        for(int i = 0; i < t.size(); i++)
        {
            hashVec[t[i] - 'a']--;    
        }
        bool flag = true;
        for(int i = 0; i < hashVec.size(); i++)
        {
            if(hashVec[i] != 0)
            {
                flag = false;
                break;
            }
        }
        return flag;
    }
};

leetcode 383 赎金信

class Solution {
public:
    bool canConstruct(string ransomNote, string magazine) {
        vector<int> hashVec(26, 0);
        for(int i = 0; i < magazine.size(); i++)
        {
            hashVec[magazine[i] -'a']++;
        }
        for(int i = 0; i < ransomNote.size(); i++)
        {
            hashVec[ransomNote[i] - 'a']--;    
        }
        bool flag = true;
        for(int i = 0; i < hashVec.size(); i++)
        {
            if(hashVec[i] < 0)
            {
                flag = false;
                break;
            }
        }
        return flag;
    }
};

leetcode 49 字母异位词分组

class Solution {
public:
	vector<vector<string>> groupAnagrams(vector<string>& strs) {
		map<vector<int>, vector<string>> umap;
		vector<vector<string>> result;
		for (int i = 0; i < strs.size(); i++)
		{
			string str = strs[i];
			vector<int> hashVec = convertStr(str);
			if (umap.find(hashVec) == umap.end())
			{
				umap[hashVec] = vector<string>();
			}
			umap[hashVec].push_back(str);
		}
		map<vector<int>, vector<string>>::iterator it;
		for (it = umap.begin(); it != umap.end(); it++)
		{
			result.push_back(it->second);
		}
		return result;
	}
	vector<int> convertStr(string str)
	{
		vector<int> hashVec(26, 0);
		for (int i = 0; i < str.size(); i++)
		{
			hashVec[str[i] - 'a']++;
		}
		return hashVec;
	}
};
class Solution {
public:
	vector<vector<string>> groupAnagrams(vector<string>& strs) {
		unordered_map<string, vector<string>> umap;
		vector<vector<string>> result;
		for (int i = 0; i < strs.size(); i++)
		{
			string str = strs[i];
            sort(str.begin(), str.end());
			if (umap.find(str) == umap.end())
			{
				umap[str] = vector<string>();
			}
			umap[str].push_back(strs[i]);
		}
		unordered_map<string, vector<string>>::iterator it;
		for (it = umap.begin(); it != umap.end(); it++)
		{
			result.push_back(it->second);
		}
		return result;
	}
};

leetcode 138 复制带随机指针的链表

class Solution {
public:
    Node* copyRandomList(Node* head) {
        unordered_map<Node*, int> umap;   // Node address --->  vector index
        vector<Node*> newNode;
        Node* ptr = head;
        if(!head) return NULL;
        int k = 0;
        while(ptr != NULL)
        {
            umap.insert(pair<Node*, int>(ptr, k));
            newNode.push_back(new Node(ptr->val));
            ptr = ptr->next;
            k++;
        }
        ptr = head;
        k = 0;
        newNode.push_back(NULL);   //为了在下面链接新节点的next指针不用特殊处理最后一个Node
        while(ptr != NULL)
        {
            newNode[k]->next = newNode[k+1];
            Node* tmp = ptr->random;
            if(tmp != NULL)
            {
                int id = umap[tmp];
                newNode[k]->random = newNode[id]; 
            }
            else
            {
                newNode[k]->random = NULL;
            }
            ptr = ptr->next;
            k++;
        }
        return newNode[0];
    }
};

leetcode 1002 查找共用字符

class Solution {
public:
    vector<string> commonChars(vector<string>& words) {
        vector<int> hashVec(26, 0);
        for(int i = 0; i < words[0].size(); i++)
        {
            hashVec[words[0][i] - 'a']++;
        }
        int hashOtherStr[26] = {0};
        for(int i = 1; i < words.size(); i++)
        {
            memset(hashOtherStr, 0, 26 * sizeof(int));   //别忘了恢复hashOtherStr的状态
            for(int j = 0; j < words[i].size(); j++)
            {
                hashOtherStr[words[i][j] - 'a']++;
            }
            for(int k = 0; k < 26; k++)
            {
                hashVec[k] = hashVec[k] < hashOtherStr[k] ? hashVec[k] : hashOtherStr[k];
            }
        }
        vector<string> result;
        for(int k = 0; k < 26; k++)
        {
            while(hashVec[k])
            {
                string s(1, k + 'a');   //char -- string
                result.push_back(s);
                hashVec[k]--;
            }
        }
        return result;
    }
};

leetcode 349 两个数组的交集

class Solution {
public:
    vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {
        unordered_set<int> tmpSet;
        unordered_set<int> uset(nums1.begin(), nums1.end());
        for(int i = 0; i < nums2.size(); i++)
        {
            if(uset.find(nums2[i]) != uset.end())
            {
                tmpSet.insert(nums2[i]);
            }
        }
        vector<int> result(tmpSet.begin(), tmpSet.end());
        return result;
    }
};

leetcode 350 两个数组的交集II

class Solution {
public:
    vector<int> intersect(vector<int>& nums1, vector<int>& nums2) {
        vector<int> result;
        unordered_map<int, int> umap;
        for(auto ele : nums1)
        {
            umap[ele]++;
        }
        for(auto ele : nums2)
        {
            if(umap[ele] > 0)
            {
                result.push_back(ele);
                umap[ele]--;
            }
        }
        return result;
    }
};

leetcode 202 快乐数

class Solution {
public:
    bool isHappy(int n) {
        unordered_set<int> uset;
        while(1)
        {
            int sum = getSum(n);
            if(sum == 1)
            {
                return true;
            }
            else
            {
                if(uset.find(sum) != uset.end())
                {
                    return false;
                }
                uset.insert(sum);
                n = sum;
            }
        }
    }
    int getSum(int n)
    {
        int sum = 0;
        while(n)
        {
            sum += (n % 10) * (n % 10);
            n = n / 10;
        }
        return sum;
    }
};

leetcode 1 两数之和

class Solution {
public:
    vector<int> twoSum(vector<int>& nums, int target) {
        unordered_map<int, int> mp;   //key无序 key不可重复
        vector<int> result;
        for(int i = 0; i < nums.size(); i++)
        {
            auto it = mp.find(target - nums[i]);  //固定一个元素,在之前的元素集合中找另一个
            if(it != mp.end()) 
            {
                result.push_back(it->second);
                result.push_back(i);
            }
            mp.insert(pair<int, int>(nums[i], i));
        }
        return result;
    }
};

leetcode 15 三数之和

class Solution {
public:
	vector<vector<int>> threeSum(vector<int>& nums) {
		vector<vector<int>> result;
		sort(nums.begin(), nums.end());

		int size = nums.size();

		if (nums.empty() || nums.back() < 0 || nums.front() > 0)
		{
			return {};
		}

		for (int i = 0; i < size - 2; i++)
		{
			if (nums[i] > 0)
			{
				break;
			}

            if(i > 0 && nums[i] == nums[i-1])
            {
                continue;
            }

			int fix = nums[i];
			int target = 0 - fix;

			int first = i + 1;
			int last = size - 1;

			while (first < last)
			{
				if (nums[first] + nums[last] == target)
				{
					result.push_back( {nums[i], nums[first], nums[last]} );

					while (first < last && nums[first] == nums[first + 1])
					{
						first++;
					}
					while (first < last && nums[last] == nums[last - 1])
					{
						last--;
					}

					first++;
					last--;
				}
                else if (nums[first] + nums[last] < target)
				{
					first++;
				}
				else
				{
					last--;
				}
			}
		}
		return result;
	}
};
class Solution {
public:
    vector<vector<int>> threeSum(vector<int>& nums) {
        vector<vector<int>> result;
        sort(nums.begin(), nums.end());

        if(nums.size() == 0 || nums.front() > 0 || nums.back() < 0)
        {
            return result;
        }
        
        for(int i = 0; i < nums.size(); i++)
        {
            int left = i + 1;
            int right = nums.size() - 1;
            
            if(i > 0 && nums[i] == nums[i-1])
            {
                continue;
            }

            while(left < right)
            {
                if(nums[i] + nums[left] + nums[right] > 0)
                {
                    right--;
                }
                else if (nums[i] + nums[left] + nums[right] < 0)
                {
                    left++;
                }
                else
                {
                    result.push_back(vector<int>{nums[i], nums[left], nums[right]});
                    
                    while(left < right && nums[left] == nums[left+1])  // 去重逻辑应该放在找到一个三元组之后
                    {
                        left++;  
                    }
                    while(left < right && nums[right] == nums[right-1])
                    {
                        right--;
                    }

                    left++;    // 找到答案时,双指针同时收缩
                    right--;
                }
            }
        }
        return result;
    }
};

leetcode 18 四数之和

class Solution {
public:
    vector<vector<int>> fourSum(vector<int>& nums, int target) {
        vector<vector<int>> result;
        sort(nums.begin(), nums.end());

        for(int i = 0; i < nums.size(); i++)
        {
            if(i > 0 && nums[i] == nums[i-1])
            {
                continue;
            }
            for(int k = i + 1; k < nums.size(); k++)
            {
                if(k > i + 1 && nums[k] == nums[k-1])
                {
                    continue;
                }
                int left = k + 1;
                int right = nums.size() - 1;

                while(left < right)
                {
                    //if(nums[i] + nums[k] + nums[left] + nums[right] > target) 会溢出
                    if(nums[i] + nums[k] > target - (nums[left] + nums[right]))
                    {
                        right--;
                    }
                    else if (nums[i] + nums[k] < target - (nums[left] + nums[right]))
                    {
                        left++;
                    }
                    else
                    {
                        result.push_back(vector<int>{nums[i], nums[k], nums[left], nums[right]});
                    
                        while(left < right && nums[left] == nums[left+1])  // 去重逻辑应该放在找到一个三元组之后
                        {
                            left++;  
                        }
                        while(left < right && nums[right] == nums[right-1])
                        {
                            right--;
                        }

                        left++;    // 找到答案时,双指针同时收缩
                        right--;
                    }
                }
            }
        }        
        return result;
    }
};

leetcode 454 四数相加II

class Solution {
public:
    int fourSumCount(vector<int>& nums1, vector<int>& nums2, vector<int>& nums3, vector<int>& nums4) {
        unordered_map<int, int> umap;   // key --> a+b  value --> a+b出现的次数 
        for(auto a : nums1)
        {
            for(auto b : nums2)
            {
                umap[a+b]++;
            }
        }
        int count = 0;     //计算a+b+c+d出现的次数
        for(auto c : nums3)
        {
            for(auto d : nums4)
            {
                if(umap.find(0 - (c+d)) != umap.end())
                {
                    count += umap[0 -(c+d)];
                }
            }
        }
        return count;
    }
};


这篇关于leetcode 哈希表相关算法刷题笔记的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程