0
点赞
收藏
分享

微信扫一扫

【数据结构/哈希表】题解+详细备注(共11题)

王老师说 2022-04-13 阅读 15

【数据结构/哈希表】题解+备注

242.有效的字母异位词

class Solution {
public:
	// 使用数组计数
    bool isAnagram(string s, string t) {
        vector<int> sArr(26);
		// 记录字符串s的各字符数量
        for(char c : s){
            sArr[c - 'a']++;
        }
		
		// 进行各字符数量的匹配
        for(char c : t){
            if(sArr[c- 'a'] == 0) return false;
            
            sArr[c- 'a']--;
        }

		// 最后校验是否所有字符都完全匹配到了
        return accumulate(sArr.begin(),sArr.end(),0) == 0;
    }
};

383.赎金信

class Solution {
public:
	// 使用数组计数
    bool canConstruct(string ransomNote, string magazine) {
        int unmap[26] = {0};
		// 记录字符串magazine的字符数量
        for(char c : magazine){
            unmap[c - 'a']++;
        }
		// 进行匹配
        for(char c : ransomNote){
            unmap[c-'a']--;

            if(unmap[c-'a'] < 0) return false;
        }

        return true;
    }
};

49.字母异位词分组

class Solution {
public:
	// 通过关联式容器计数
    vector<vector<string>> groupAnagrams(vector<string>& strs) {
        unordered_map<string, vector<string>> mp;
		// 统计各个字符串的数量
        for (string& str: strs) {
            string key = str;
            sort(key.begin(), key.end());
            mp[key].emplace_back(str);
        }
        // 返回答案
        vector<vector<string>> ans;
        for (auto it = mp.begin(); it != mp.end(); ++it) {
            ans.emplace_back(it->second);
        }
        return ans;
    }
};

438.找到字符串中所有字母异位词

class Solution {
public:
	// 使用数据进行计数,并配合滑动窗口思想
    vector<int> findAnagrams(string s, string p) {
        int slen = s.size();
        int plen = p.size();

        if(slen < plen) return{};

        vector<int> sArr(26);
        vector<int> pArr(26);
        vector<int> ans;
		// 统计p的字符数量
        for(char c : p){
            pArr[c - 'a']++;
        }
		// 初始化第一个窗口
        for(int i{};i<plen;++i){
            sArr[s[i] - 'a']++;
        }

        if(sArr == pArr) ans.emplace_back(0);
		// 开始进行窗口移动
        for(int i = 0;i< slen - plen;++i){
            sArr[s[i] - 'a']--; // 窗口左边界右移
            sArr[s[i + plen] - 'a']++;// 窗口扩展右边界

            if(sArr == pArr) ans.emplace_back(i+1);
        }

        return ans;
    }
};

349.两个数组的交集

class Solution {
public:
	// 使用关联式容器计数并去重
    vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {
        unordered_set<int> ans;
        unordered_set<int> set1(nums1.begin(),nums1.end());

		// 交集匹配
        for(int num : nums2){
            if(set1.find(num) != set1.end()){
                ans.insert(num);
            }
        }

        return vector<int>(ans.begin(),ans.end());
    }
};

350.两个数组的交集II

class Solution {
public:
	// 使用关联式容器计数
    vector<int> intersect(vector<int>& nums1, vector<int>& nums2) {
        unordered_map<int,int> mp1;
        unordered_map<int,int> mp2;

        vector<int> ans;

        for(int num : nums1){
            mp1[num]++;
        }

        for(int num : nums2){
            mp2[num]++;
        }
		
		// 匹配并根据最小数量输出答案
        for(auto&[key,value] : mp1){
            if(mp2.find(key) != mp2.end()){
                int minCount = min(value,mp2[key]);
                for(int i{};i < minCount;++i){
                    ans.emplace_back(key);
                }
            }
        }

        return ans;
    }
};

202.快乐数

class Solution {
public:
	// 返回数字的拆分后的平方结果
    int getSum(int n){
        int ans{};

        while(n){
            ans+=(n%10)*(n%10);
            n/=10;
        }

        return ans;
    }
    // 使用关联式容器计数
    bool isHappy(int n) {
        unordered_set<int> unS;
        while(1){
            if(1 == n) return true;
            int sumN = getSum(n);

            if(unS.find(sumN) != unS.end()){
                return false;
            }

            unS.insert(sumN);
            n = sumN;
        }

        return true;
    }
};

1.两数之和

class Solution {
public:
	// 使用关联式容器计数
    vector<int> twoSum(vector<int>& nums, int target) {
        int n = nums.size();
        unordered_map<int,int> mp;
        for(int i{};i<n;++i){
            if(mp.find(target - nums[i]) != mp.end()){
                return {i,mp[target - nums[i]]};
            }
            mp[nums[i]] = i;
        }
        return {};
    }
};

454.四数相加II

class Solution {
public:
	// 使用关联式容器计数
    int fourSumCount(vector<int>& nums1, vector<int>& nums2, vector<int>& nums3, vector<int>& nums4) {
        unordered_map<int,int> umap;

        for(int a : nums1){
            for(int b : nums2){
                umap[a + b]++;
            }
        }
        int ans{};  
        for(int a : nums3){
            for(int b :nums4){
                if(umap.find(0 -(a+b)) != umap.end()){
                    ans+= umap[0-(a+b)];
                }
            }
        }

        return ans;
    }
};

15.三数之和

class Solution {
public:
	// 使用关联式容器并配合双指针求解
    vector<vector<int>> threeSum(vector<int>& nums) {
        int n =nums.size();
        int left{},right{};
        vector<vector<int>> ans;
        sort(nums.begin(),nums.end()); // 先排序,然后使用双指针
        for(int i{};i<n;++i){
            if(i > 0 && nums[i] == nums[i-1]){
                continue;
            }

            left = i+1;
            right = n-1;
			// 双指针求解
            while(left < right){
                int sumNum = nums[i] + nums[left] + nums[right];
                if(sumNum > 0){
                    right--;
                }else if(sumNum < 0){
                    left++;
                }else{
                    ans.push_back({nums[i],nums[left],nums[right]});
                    while(left < right && nums[right] == nums[right-1]) right--;
                    while(left < right && nums[left] == nums[left+1]) left++;

                    right--;
                    left++;
                }
            }
        }

        return ans;
    }
};

18.四数之和

class Solution {
public:
	// 与三数之和一致:关联式容器+双指针求解,只是多嵌套了一层循环
    vector<vector<int>> fourSum(vector<int>& nums, int target) {
        int n = nums.size();
        int left{},right{};
        vector<vector<int>> ans;

        sort(nums.begin(),nums.end());
        for(int i{};i<n;++i){
            if(i > 0 && nums[i] == nums[i-1]){
                continue;
            }

            for(int j = i+1;j<n;++j){
                if(j > i+1 && nums[j] == nums[j-1]){
                    continue;
                }

                left = j+1;
                right = n-1;

                while(left <right){

                    if(nums[i] + nums[j] > target - (nums[left] + nums[right])){
                        right--;
                    }else if(nums[i] + nums[j] <  target - (nums[left] + nums[right])){
                        left++;
                    }else{
                        ans.push_back({nums[i], nums[j], nums[left] ,nums[right]});
                        while(left < right && nums[right] == nums[right-1]) right--;
                        while(left < right && nums[left] == nums[left+1]) left++;

                        left++;
                        right--;
                    }
                }
            }
        }

        return ans;
    }
};
举报

相关推荐

0 条评论