代码随想录算法训练营第5天|242.有效的字母异位词、349. 两个数组的交集、202. 快乐数、1. 两数之和

LeetCode242

2025-01-26 15:39:01 星期日

题目描述:力扣242
文档讲解:代码随想录(programmercarl)242.有效的字母异位词
视频讲解:《代码随想录》算法视频公开课:学透哈希表,数组使用有技巧!Leetcode:242.有效的字母异位词

代码随想录视频内容简记

梳理

  1. 使用哈希法,关于三种数据结构的选择。如果哈希值不是特别大,数组是最优先的选择,因为数组比较快。如果哈希值比较大的情况,就可以使用set,而map主要是为了应对key:value

  2. 对一个字符串遍历,其频率存放到哈希表中,进行++操作

  3. 对另一个字符串的出现频率在哈希表中进行--操作,看最后的结果是否都为0

大致代码内容

  1. 首先定义一个hash[26]。存放26个字母。之后设置一个for循环for (int i = 0; i < s.size(); i++)进行(hash[i] - "a")++

  2. 同样设置for循环进行(hash[j] - "a")--

  3. 最后设置一个循环for (int k = 0; k < 26; k++)逐个遍历检测if (hash[k] != 0) return false;

LeetCode测试

思路明白了代码比较好实现,完整代码如下

点击查看代码
class Solution {
public:
    bool isAnagram(string s, string t) {
        int hash[26];
        for (int i = 0; i < s.size(); i++) {
            hash[s[i] - 'a']++;
        }
        for (int j = 0; j < t.size(); j++) {
            hash[t[j] - 'a']--;
        }
        for (int k = 0; k < 26; k++) {
            if (hash[k] != 0) return false;
        }
        return true;
    }
};

LeetCode349

题目描述:力扣349
文档讲解:代码随想录(programmercarl)349.两个数组的交集
视频讲解:《代码随想录》算法视频公开课:学透哈希表,set使用有技巧!Leetcode:349. 两个数组的交集

代码随想录视频内容简记

使用set

适合于数值的大小没有限制,可以很大很大。同时,对于setmultisetunordered_set三种,前两种是由红黑树实现的,最后一种使用hash表的方式实现的。且setunordered_set的元素是不重复的,multiset是可以重复的

梳理

  1. num1存储到一个哈希表中

  2. num2在哈希表中进行查询

  3. 如果查询到,则保存到一个由unordered_set定义的result

  4. result转换为vector返回

大致代码内容

  1. unordered_set<int> num_set(num1.begin(), num1,end())存放num1到哈希表中

  2. num1的哈希存储和num2的查询


for (int i = 0; i < num2.size(); i++) {
	if (num_set.find(num2[i]) != num_set.end()) {
		result.insert(num2[i])
	}
	
}

感觉这个写法还是比较特殊的,尤其是这一句,if (num_set.find(num2[i]) != num_set.end()),需要额外赋一个!= num_set.end(),就是为了保证num2在nums_set中

  1. return vector<int> (result.begin(), result.end())注意强制类型转换的写法

使用数组

梳理

  1. 同样先存储num1到一个hash表

  2. 之后使用num2在hash表中进行遍历,找到符合的值添加到result

大致代码内容

  1. 同样是先建立一个哈希数组hash,存储num1,通过for循环给每个num1中的元素赋值为1

  2. 之后同样使用for循环,把num2在hash中进行遍历,如果有相等的值,则在unordered_set类型的result中添加

LeetCode测试

使用set

点击查看代码
class Solution {
public:
    vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {
        unordered_set<int> result;
        unordered_set<int> num_set(nums1.begin(), nums1.end());
        for (int i = 0; i < nums2.size(); i++) {
            if (num_set.find(nums2[i]) != num_set.end()) {
                result.insert(nums2[i]);
            }
        }
        return vector<int> (result.begin(), result.end());
    }
};

使用数组

点击查看代码
class Solution {
public:
    vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {
        unordered_set<int> result;
        int hash[1005] = {0};
        for (int i = 0; i < nums1.size(); i++) {
            hash[nums1[i]] = 1;
        }
        for (int j = 0; j < nums2.size(); j++) {
            if (hash[nums2[j]] == 1) {
                result.insert(nums2[j]);
            }
        }
        return vector<int> (result.begin(), result.end());
    }
};

LeetCode202

题目描述:力扣202
文档讲解:代码随想录(programmercarl)202. 快乐数

梳理

  1. 关键在题目中给出的“无限循环”,只要在hash表中查到了一样的值,那么直接返回false,就不是一个快乐数

  2. 在哈希表中先插入替换之前的值

  3. 进行分解和平方计算

  4. 给n赋值并在hash表中查询

LeetCode测试

需要注意的点

注意中间有一步,在每次的while循环结束之后,需要给sum重新赋值为0

关于代码的时间复杂度,力扣上给出的是O(n),我是有点不太看不出来,大家如果能看出来可以留在评论区里

快乐数完整代码

点击查看代码
class Solution {
public:
    bool isHappy(int n) {
        unordered_set<int> query;
        int sum = 0, m;
        while (n != 1) {
            // 先插入
            query.insert(n);
            // 分解和平方计算
            while (n) {
                m = (n % 10) * (n % 10);
                sum = m + sum;
                n = n / 10;
            }
            // 赋值
            n = sum;
            sum = 0;
            // cout << n << endl;
            // 查询
            if (query.find(n) != query.end()) return false;
        }
        return true;
    }
};

LeetCode1

——梦开始的地方——

题目描述:力扣1
文档讲解:代码随想录(programmercarl)1. 两数之和
视频讲解:《代码随想录》算法视频公开课:梦开始的地方,Leetcode:1.两数之和

代码随想录视频内容简记

梳理

  1. 关于这个题为什么要使用哈希法。首先,这个题的正常思路是在遍历元素时(比如3),去查找另一个对应的元素(6)是否存在于数组中,那么也即是判断“一个元素是否出现过”,所以自然就想到了哈希法

  2. 关于为什么要使用map这种哈希结构。因为本题需要在找到对应的数之后返回他的索引,也就是下标,所以我们需要查询他的值(key),并返回他的索引(value),所以应该使用map的结构

  3. map的作用是干什么的。其实就是为了存放遍历过的元素。

大致代码内容

  1. 定义一个map,unordered_map<int, int> map

  2. 遍历数组元素,并在查询与target对应的值是否存在int s = target - nums[i]if (map.find(s) != map.end())表示找到对应的值,则return {map.find(s)->value, i},如果没有找到,则向map中写入map.insert(pair<int, int>(nums[i], i))

  3. 最后没有找到则return {}

LeetCode测试

代码很好通过,完整代码如下

点击查看代码
class Solution {
public:
    vector<int> twoSum(vector<int>& nums, int target) {
        unordered_map<int, int> map;
        for (int i = 0; i < nums.size(); i++) {
            int s = target - nums[i];
            if (map.find(s) != map.end()) return {map.find(s)->second, i};
            map.insert(pair<int, int>(nums[i], i));
        }
        return {};
    }
};
posted on   bnbncch  阅读(2086)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 零经验选手,Compose 一天开发一款小游戏!
· 因为Apifox不支持离线,我果断选择了Apipost!
· 通过 API 将Deepseek响应流式内容输出到前端
点击右上角即可分享
微信分享提示