代码随想录算法 Day6 | Ch3 哈希表(一)● 242.有效的字母异位词 ● 349. 两个数组的交集 ● 202. 快乐数● 1. 两数之和

一、有效的字母异位词

        1.题目:给定两个字符串 s 和 t ,编写一个函数来判断 t 是否是 s 的字母异位词。

                Ps:若 s 和 t 中每个字符出现的次数都相同,则称 s 和 t 互为字母异位词。

        2.思路:哈希表

        3.注意:

                无需创建两个数组,在对 s 的字母统计时在哈希表上递增,在统计 t 时递减即可。

        4.代码:

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++) {
            if (record[i] != 0) {
                // record数组如果有的元素不为零0,说明字符串s和t 一定在该元素的数量不等
                return false;
            }
        }
        // record数组所有元素都为零0,说明字符串s和t是字母异位词
        return true;



    }
};

二、 两个数组的交集

        1.题目:给定两个数组 nums1 和 nums2 ,返回它们的交集。输出结果中的每个元素一定是 唯一 的。我们可以不考虑输出结果的顺序 。

        2.思路:哈希表

        3.注意:

           题目说的时输出中元素唯一,不是输入数组里元素唯一,所以在哈希表里对位置代表的元素加一后判断是否为2的方法不可行。

        4.代码:

        (1)方法一

class Solution {
public:
    vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {
        int record1[1001] = {0};
        int record2[1001] = {0};
        vector<int> res;

        for(int i=0; i<nums1.size(); i++)
        {
            record1[nums1[i]] = 1;
        }

        for(int i=0; i<nums2.size(); i++)
        {
            record2[nums2[i]] = 1;
        }

        for(int i=0; i<1001; i++)
        {
            if( record1[i]==1 && record2[i]==1 )
            {
                res .push_back(i);
            }

        }

        return res;
    }
};

        (2)方法二:使用容器 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());
    }
};

三、快乐数

        1.题目:编写一个算法来判断一个数 n 是不是快乐数。

        「快乐数」 定义为:

                对于一个正整数,每一次将该数替换为它每个位置上的数字的平方和。

                然后重复这个过程直到这个数变为 1,也可能是 无限循环 但始终变不到 1。

                如果这个过程 结果为 1,那么这个数就是快乐数。

          如果 n 是 快乐数 就返回 true ;不是,则返回 false 。

        2.思路:哈希表,使用容器 set

        3.注意:

        4.代码:

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;
        }
    }
};

四、两数之和 

        1.题目:给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 target  的那 两个 整数,并返回它们的数组下标。

        你可以假设每种输入只会对应一个答案,并且你不能使用两次相同的元素。

        你可以按任意顺序返回答案。

        2.思路:检测 target - nums[i] 是否被记录了即可

        3.注意:

        4.代码:

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 {};
    }
};

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值