有效的字母异位词,两个数组的交集,快乐数,两数之和

67 阅读1分钟

有效的字母异位词

[题目](242. 有效的字母异位词)

思路

使用哈希法 哈希的数据结构有三种:数组,set,map 这里我们使用数组,因为字母是26个连续的数值

代码实现

class Solution {
public:
    bool isAnagram(string s, string t) {
        int record[26] = {0};
        // 算出每个字母出现的频率
        for(int i = 0; i < s.size(); i++) {
            record[s[i] - 'a']++;
        }
        for(int i = 0; i < t.size(); i++) {
            record[t[i] - 'a']--;
        }
        for(int i = 0; i < 26; i++) {
            // 如果有元素不为0,说明s和t的字符不一样
            if (record[i] != 0) {
                return false;
            }
        }
        return true;
    }
};

两个数组的交集

[题目](349. 两个数组的交集)

思路

哈希表算法最适合解决的场景就是给一个元素,判断这个元素在这个集合中是否出现过 数组不适合哈希值比较少,特别分散,跨度非常大的情况,这样会造成空间的极大浪费。 std::set:底层实现是红黑树 std::multiset:底层实现是红黑树 std::unordered_set:实现是哈希表,读写效率最高,并且不需要排序

代码实现

class Solution {
public:
    vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {
        unordered_set<int> result;
        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.insert(num);
            }
        }
        return vector<int>(result.begin(), result.end());
    }
};

快乐数

[题目](202. 快乐数)

思路

重点是无限循环,如果出现无限循环,求和的值重复出现,当重复出现时,需要中断循环,否则一直找到和为1的时候

代码实现

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;
            }
            if (set.find(sum) != set.end()) {
                return false;
            }
            set.insert(sum);
            n = sum;
        }
    }
};

两数之和

[题目](1. 两数之和)

思路

不仅要直到元素有没有遍历过,还要知道这个元素对应的下标,所以需要使用到map std::unordered_map:实现是哈希表 std::map:实现是红黑树 std::multimap:实现是红黑树

代码实现

class Solution {
public:
    vector<int> twoSum(vector<int>& nums, int target) {
        std::unrodered_map<int, int> map;
        for (int i = 0; i < nums.size(); i++) {
            // 如果找到,则直接返回对应下标
            auto it = map.find(target - nums[i]);
            if (it != map.end()) {
                return {it->second, i};
            }
            // 如果没找到,就需要把访问过的元素和下标放到map中
            map.insert(pair<int, int>(nums[i], i));
        }
        return {};
    }
};