代码随想录 Day6 哈希表 哈希表理论基础, 242.有效的字母异位词, 349. 两个数组的交集,202. 快乐数,1. 两数之和

这篇具有很好参考价值的文章主要介绍了代码随想录 Day6 哈希表 哈希表理论基础, 242.有效的字母异位词, 349. 两个数组的交集,202. 快乐数,1. 两数之和。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

yi  哈希表理论基础

哈希表是采用了牺牲空间换取时间,因为需要存储额外的数据。

需要快速判断一个元素是否出现在一个 数组中的时候就需要哈希法。

er  242.有效的字母异位词

本题一开始想到的是使用map,感觉是字母和数字的组合

class Solution {
public:
    bool isAnagram(string s, string t) {
        int record[26] = {0};
        for (int i = 0; i < s.size(); i++) {
            // 并不需要记住字符a的ASCII,只要求出一个相对数值就可以了
            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. 注意给'a'穿衣服

2.想到其实这样一种思路就已经用到了哈希表

er  349.两个数组的交集

本题一开始还是想要用1000个元素的数组哈希借了上一题的思路,也可以ac

(1)数组

vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {
        unordered_set<int> result;
        int record[1010];
        for(int i = 0; i < nums1.size(); i++){
            record[nums1[i]] = 1;
        }
        for(int i = 0; i < nums2.size(); i++){
            if(record[nums2[i]] == 1){
            result.insert(nums2[i]);
            }
        }
        return vector<int>(result.begin(),result.end());
    }

(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. string 和vector中存储数据的或者字母的多少都可以通过.size()获取

2. unorder_set 可以直接帮助去重,这个地方也用到它的底层原理,unordered_set的底层是哈希表所以说这样在查找一个元素的时候O(1)

3.for(int num : nums2)表示遍历nums2中的每一个元素,end()指向最后一个有效的元素的下一个位置

san 202.快乐数

本题一个主要的难点也是在于如果不能够找到的话就传回不行,所以说需要判断是否曾经出现过相同的值的元素,这个地方使用unordered_set,如果说后来又出现了原来的元素的话采用find方法检查

(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;
            }
            // 如果这个sum曾经出现过,说明已经陷入了无限循环了,立刻return false
            if (set.find(sum) != set.end()) {
                return false;
            } else {
                set.insert(sum);
            }
            n = sum;
        }
    }
};

(2)自己思路

bool isHappy(int n) {
        multiset<int> record;
        unordered_set<int> result;
        while(1){
            result.insert(n);
            while(n != 0){
                record.insert(n%10);
                n /= 10;
            }
        
            while(!record.empty()){
                int num = *record.begin();
                n += num * num;
                record.erase(record.begin());
            }
            if(n == 1) return true;
            if(result.find(n) != result.end()){
                return false;
            }
        }
    }

问题:

1.  主要是注意循环的条件设置,每个条件式位置的设置可能出现错误

例如while(1),result.insert(x)不能设置在while循环中

si  1.两数之和

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

问题:

1. 算法思路有难度尤其是对于map并不熟悉的时候,是将访问过的元素放入到map,后续遍历的时候不断向前去比对从集合中查找有没有符合的元素即哈希法。

哈希法中有vector,set,map,因为我们需要保存元素值和下标值所以采用map,因为我们需要检查map中有没有存在的相应的元素值即key代表元素值。

在map中还有三种存储形式,分别是map,multimap,unordered_map,因为unordered_map的底层实现是哈希表所以说查找的效率更高。

2. map的书写要求:

类型用auto,因为是迭代器。

return {1,2};可以这样写

unordered_map<int,int> map  其中的map也可以作为名称,如果担心可以不用这个

map插入元素时:map.insert(pair< int, int >( x, y));

return {} 明明说一定会有返回值,但力扣还得要有一个这个

基础知识:

1.不适合使用数组的情况:数据量很大时,数据很分散(0,1,1000000)

这个时候考虑使用set和map

2.set系列也分为set,unorder_set,mult_set。

三者都不能修改元素的值,理解毕竟红黑树和哈希表,可以进行增删。

set和multiset的底层实现都是红黑树,要求数据是有序的,然后一个可以数据是重复的一个不能重复。unorder_set的底层实现是哈希表,所以说在查找元素和增删的时候效率都是非常高的。

3. 注意unordered_set转vector的写法:

另存时只是作为return,不需要名称vector<int>(result.begin(),result.end());

另存时,需要名称last:vector<int> last(result.begin(),result.end())

4.set的元素输入的方式是.insert(x),vector的元素输入的方式是.push_back(x)

5.set也是有begin(),end()。set通过insert放入元素,通过erase取出元素

6.set中*record.begin()表示迭代器指向的元素,vector中同样如此。文章来源地址https://www.toymoban.com/news/detail-837586.html

到了这里,关于代码随想录 Day6 哈希表 哈希表理论基础, 242.有效的字母异位词, 349. 两个数组的交集,202. 快乐数,1. 两数之和的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 代码随想录刷题day6

    242.有效的字母异位词 用数组实现哈希; 注意初始化; int storage[26] = {0}; //定义数组的方法:  数据类型  数组名[数组长度]; 这时候index从 0 - 25;注意要初始化这个数组,不初始化会报错 349. 两个数组的交集 用unoderset来实现哈希,注意unorderset容器内部直接就做了去重操作 要

    2024年02月03日
    浏览(38)
  • 代码随想录day3|链表理论基础、移除链表元素、设计链表、翻转链表

    1、基本类型:单链表、双链表、循环链表 2、存储方式:和数组不一样,链表是随机存储在内存中,不是连续分配在内存中。 3、链表的定义: 定义了一个数据域,还有一个指针域,并且定义了一个构造函数。 4、链表的操作: 删除节点:  在图中,若需要删除D这个节点,只

    2024年02月05日
    浏览(32)
  • 代码随想录Day3|链表理论基础|203.移除链表元素|707.设计链表|206.反转链表

    虽然以前写过一次链表,但是真的已经忘得一干二净了 链表 :通过 指针 串联在一起的线性结构,每个 节点 都由数据域和指针域组成。 指针域 :存放下一个节点的指针,最后一个节点的指针域指向null,也即空指针 head :链表的入口节点,也即链表的头节点 链表的类型 单

    2024年02月11日
    浏览(42)
  • Day7代码随想录(1刷) 哈希表

    目录 454. 四数相加 II  383. 赎金信 15. 三数之和  18. 四数之和   给你四个整数数组  nums1 、 nums2 、 nums3  和  nums4  ,数组长度都是  n  ,请你计算有多少个元组  (i, j, k, l)  能满足: 0 = i, j, k, l n nums1[i] + nums2[j] + nums3[k] + nums4[l] == 0 示例 1: 示例 2:    提示: n == nums1.l

    2024年03月25日
    浏览(37)
  • 代码随想录第6天| 哈希表理论基础 ,LeetCode242.有效的字母异位词,LeetCode349. 两个数组的交集,LeetCode202. 快乐数,LeetCode1. 两数之和

    哈希表(散列表)理论基础 : 哈希表是根据关键码的值而直接进行访问的数据结构。 直白来讲其实数组就是一张哈希表。   什么时候想到用哈希法, 当我们遇到了要快速判断一个元素是否出现集合里的时候,就要考虑哈希法 。 当我们遇到了要快速判断一个元素是否出现集

    2024年02月10日
    浏览(39)
  • 代码随想录二刷 day06 | 哈希表之 242.有效的字母异位词 349. 两个数组的交集 202. 快乐数 1. 两数之和

    哈希表能解决什么问题呢?一般哈希表都是用来快速判断一个元素是否出现集合里。 242.有效的字母异位词 题目链接 解题思路: 题目的意思就是 判断两个字符串是否由相同字母组成。 字符a到字符z的ASCII是26个连续的数值,所以字符a映射为下标0,相应的字符z映射为下标25。

    2024年02月07日
    浏览(35)
  • 代码随想录第44天|动态规划:完全背包理论基础 518.零钱兑换II 377. 组合总和 Ⅳ

    代码随想录 (programmercarl.com) 动态规划之完全背包,装满背包有多少种方法?组合与排列有讲究!| LeetCode:518.零钱兑换II_哔哩哔哩_bilibili 完全背包和01背包问题唯一不同的地方就是,每种物品有无限件 。 完全背包中的物品可以添加多次,所以要从小到大遍历: 518. 零钱兑换

    2024年04月25日
    浏览(32)
  • 代码随想录打卡—day41—【DP】— 8.26+27 DP基础3

    343. 整数拆分 一开始做 没有思路,学习了题解才,ac代码: 后来仔细看题解,其实 for - j 的次数可以优化—— 注意 枚举j的时候,是从1开始的。从0开始的话,那么让拆分一个数拆个0,求最大乘积就没有意义了。 优化1: j 的结束条件是 j i - 1 ,其实 j i 也是可以的,不过

    2024年02月11日
    浏览(27)
  • 代码随想录 -- 哈希表--两数之和

    力扣hot1:两数之和 给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标。 你可以假设每种输入只会对应一个答案。但是,数组中同一个元素不能使用两遍。 示例: 给定 nums = [2, 7, 11, 15], target = 9 因为 nums[0] +

    2024年02月09日
    浏览(29)
  • 第10天-代码随想录刷题训练-第五章 栈和队列- ● 理论基础 ● 232.用栈实现队列 ● 225. 用队列实现栈

    栈和队列对应的三个不同的STL版本,底层实现方式不一样, 为我们所知道的是 SGI STL 栈 栈提供 pop和push等接口, 不提供走访功能 也不提供迭代器, 不像map和set可以使用迭代器遍历,往往不被归类为容器,而是容器适配器 栈的内部实现结构可以使用 verctor、list 和 deque(默认)

    2024年02月04日
    浏览(28)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包