代码随想录day6 哈希初探

文章讨论了字符串的字母异位词判断,利用哈希数组简化字符计数;涉及数组交集问题,使用set求解唯一元素;快乐数问题通过递归和哈希集合检测无限循环;最后是两数之和的经典LeetCode问题,分析了暴力法和使用哈希映射的方法。
摘要由CSDN通过智能技术生成

242.有效的字母异位词

题目

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

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

示例 1:

输入: s = "anagram", t = "nagaram" 输出: true

思考

初看题目,有相同字符和出现次数两个关键词,想用map将两个数组的关键词都存下来,然后遍历map来比较,感觉比较麻烦但思路OK,后面看讲解视频发现还可以用数组来做,因为关键是题目说明string里只有小写字母,则用 hash(s[i]-'a') 可以表示 s[i] 在长度为26的hash数组里出现的位置,随后将遍历两个string将hash数组++,--,最后判断hash数组里的元素是否全为0即可(其实我觉得用map的方法比较通用hhh)

代码

// 数组

class Solution {

public:

    bool isAnagram(string s, string t)

    {

        int hash[26] = {0};

        for (int i = 0; i < s.length(); i++)

            hash[s[i] - 'a']++;  // 因为字符串里只有a-z,那么字符串里每个字符-‘a’就是其在数组里的位置

        for (int i = 0; i < t.length(); i++)

            hash[t[i] - 'a']--;

        for (auto i : hash) {

            if (i != 0)

                return false;

        }

        return true;

    }

};

// map

class Solution {

public:

    bool isAnagram(string s, string t)

    {

        unordered_map<char, int> maps, mapt;

        for (auto c : s) {

            if (maps.find(c) != maps.end())

                maps[c]++;

            else

                maps.insert({c, 1});

        }

        for (auto c : t) {

            if (maps.find(c) != maps.end())

                mapt[c]++;

            else

                mapt.insert({c, 1});

        }

        if (maps.size() != mapt.size())

            return false;

        for (auto it : maps) {

            if (mapt[it.first] != it.second || mapt.find(it.first) == mapt.end())

                return false;

        }

        return true;

    }

};

349. 两个数组的交集

题目

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

示例 1:

输入:nums1 = [1,2,2,1], nums2 = [2,2]
输出:[2]

思考

既然题目说说明每个元素一定是唯一的,那么用set再合适不过了,直接将nums1、nums2变成set,然后遍历nums2,如果nums1中发现有nums2的元素,则将该元素储存在一个结果vector中,需要注意的是vector变成set的方法是set(vector.begin(), vector.end()),在set中寻找value的方法是set.find(value) != set.end()

代码

class Solution {

public:

    vector<int> intersection(vector<int> &nums1, vector<int> &nums2)

    {

        vector<int> result;

        unordered_set<int> set1(nums1.begin(), nums1.end());

        unordered_set<int> set2(nums2.begin(), nums2.end());

        for (auto it : set2) {

            if (set1.find(it) != set1.end())

                result.push_back(it);

        }

        return result;

    }

};

第202题. 快乐数

题目

编写一个算法来判断一个数 n 是不是快乐数。

「快乐数」定义为:对于一个正整数,每一次将该数替换为它每个位置上的数字的平方和,然后重复这个过程直到这个数变为 1,也可能是 无限循环 但始终变不到 1。如果 可以变为  1,那么这个数就是快乐数。

如果 n 是快乐数就返回 True ;不是,则返回 False 。

示例:

输入:19
输出:true
解释:
1^2 + 9^2 = 82
8^2 + 2^2 = 68
6^2 + 8^2 = 100
1^2 + 0^2 + 0^2 = 1

思考

看到无限循环,立马反应过来需要用递归,但一直没明白这题和哈希有啥关系,因为当时想的是如果两次计算的结果一致,那么就return false,在while里存一个tmp,判断其是否等于sum就好,后看题解才发现原来是用set来做这操作,殊途同归,这题有两个关键:

1、一个数的每个位置上的数字,需要用n%10来表示

2、while循环条件是无限循环,即while(1),在循环里用条件来判断是否退出

代码

class Solution {

int calculate(int n) {

    int sum = 0;

    while(n > 0) {

        int digit = n%10;

        sum += pow(digit,2);

        n/=10;

    }

    return sum;

}

public:

    bool isHappy(int n) {

        unordered_set<int> set1;//set的作用用来结束循环

        while(1) {

            int sum = calculate(n);

            if(sum == 1) return true;

            if(set1.find(sum) != set1.end()) return false;

            else set1.insert(sum);

            n = sum;

        }

    }

};

1. 两数之和

题目

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

思考

古老,古老,再古老的题目,所有刷过leetcode人都做过这题,两种方法,暴力和用map,暴力不多追谁,map方法的核心思想是遍历nums时用map.find(target-nums[i])的方法来判断是否有符合条件的数,如果有,将两个坐标返回,如果没有,map添加该元素和其位置。

代码

// map

class Solution {

public:

    vector<int> twoSum(vector<int>& nums, int target) {

        unordered_map<int,int> map1;

        for (int i = 0; i < nums.size(); i++) {

            if(map1.find(target - nums[i]) != map1.end()) return {i, map1[target - nums[i]]};

            else map1.insert({nums[i], i});

        }

        return {};

    }

};    

// 暴力

class Solution {

public:

    vector<int> twoSum(vector<int>& nums, int target) {

        int n = nums.size();

        vector<int> res;

        for (int i = 0; i < n; i++) {

            for (int j = i+1; j < n; j++) {

                if (nums[i] + nums[j] == target) {

                    res.insert(res.end(), {i,j});

                }

            }

        }

        return res;

    }

};

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值