# 有效的字母异位词

题目链接🔗

class Solution {
public:
    bool isAnagram(string s, string t) {
        int a[26] = {0};
        /* 记录 s 和 t 中每个字母出现的次数 */
        for(int i = 0; i < s.size(); i++) {
            a[s[i] - 'a']++;
        }
        for(int i = 0; i < t.size(); i++) {
            a[t[i] - 'a']--;
        }
        for(int i = 0; i < 26; i++) {
            // 如果 a 中有非 0 值,则不为字母异位词
            if(a[i] != 0)
                return false;
        }
        return true;
    }
};

# 两个数组的交集

题目链接🔗

要考虑去重,同时可以不考虑输出顺序。

因为题目限制了数组的元素数值<=1000<=1000,因此可以使用数组来做哈希表。

class Solution {
public:
    vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {
        int a[1005] = {0};
        vector<int> result;
        /** 
         * 记录 nums1 中的元素
         * 因为要去重,所以记录为固定值
         **/
        for(int num : nums1)
            a[num] = 1;
        for(int num:nums2) {
            //nums2 的值在 nums1 中出现时记录结果,同时去重
            if(a[num] == 1) {
                result.push_back(num);
                a[num] = 0;
            }
        }
        return result;
    }
};

若题目没有限制数值大小,使用 set。

class Solution {
public:
    vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {
        unordered_set<int> result_set; // 存放结果,之所以用 set 是为了给结果集去重
        unordered_set<int> nums_set(nums1.begin(), nums1.end());
        for (int num : nums2) {
            // 发现 nums2 的元素 在 nums_set 里又出现过
            if (nums_set.find(num) != nums_set.end()) {
                result_set.insert(num);
            }
        }
        return vector<int>(result_set.begin(), result_set.end());
    }
};

# 快乐数

题目链接🔗

题目中说会无限循环,换句话来说在求和的过程中,sum 会重复出现。

判断 sum 是否在之前的求和过程中出现过。

如果出现过,则直接 false。

如果没出现过,则继续求和过程。如果 sum == 1 ,则返回 true。

class Solution {
public:
    int getSum(int n) {
        int sum = 0;
        while(n) {
            sum += (n %10) * (n % 10);
            n /= 10;
        }
        return sum;
    }
    bool isHappy(int n) {
        unordered_set<int> set;
        while(1) {
            int sum = getSum(n);
            if (sum == 1) {
                return true;
            }
            // 如果这个 sum 曾经出现过,说明已经陷入了无限循环了,立刻 return false
            if (set.find(sum) != set.end()) {
                return false;
            } else {
                set.insert(sum);
            }
            n = sum;
        }
    }
};

# 两数之和

题目链接🔗

暴力:双 for 循环寻找相加等于 target 的两个元素。

可以使用哈希表来降低时间复杂度。

因为题目需要返回数组下标,可以使用 map 来存取元素及其对应的下标。

在遍历数组的时候,只需要向 map 去查询是否有和目前遍历元素匹配的数值,如果有,就找到的匹配对,如果没有,就把目前遍历的元素放进 map 中,因为 map 存放的就是我们访问过的元素。

class Solution {
public:
    vector<int> twoSum(vector<int>& nums, int target) {
        std::unordered_map <int,int> map;
        for(int i = 0; i < nums.size(); i++) {
            // 遍历当前元素,并在 map 中寻找是否有匹配的 key
            auto iter = map.find(target - nums[i]); 
            if(iter != map.end()) {
                return {iter->second, i};
            }
            // 如果没找到匹配对,就把访问过的元素和下标加入到 map 中
            map.insert(pair<int, int>(nums[i], i)); 
        }
        return {};
    }
};