C++刷题笔记(8)——leetcode242、349、202

哈希表理论基础

1.代码随想录-哈希表
2.详解什么是哈希表
3.一文彻底搞定哈希表!

题目1:242.两两交换链表中的节点

在这里插入图片描述

解法:哈希表

解题思路:
如果t是s的字母异位词,那么两个字符串中出现的字符种类和个数一定相等

可以定义一个大小为26的数组table来记录字符串s中字符出现的次数(26个字母且都是小写),把字符映射到数组也就是哈希表的索引下标上

先遍历记录字符串s中出现的字符和种类,在遍历的时候只需要将s[i] - ‘a’ 所在的元素做+1 操作即可

然后遍历字符串t,减去table中对应的频次,如果出现table[i]<0,则说明t包含一个s中不存咋的字符。
在这里插入图片描述

class Solution {
public:
    bool isAnagram(string s, string t) {
        vector<int> table(26, 0);              
        for (int i = 0; i < s.size(); i++) {   //遍历字符串A
            table[s[i] - 'a']++;               //s[i]字符转化为字母
        }
        for (int i = 0; i < t.size(); i++) {  //遍历字符串B
            table[t[i] - 'a']--;
        }
        for (int i = 0; i < 26; i++) {        //record数组如果有的元素不为零0,说明字符串s和t 一定是谁多了字符或者谁少了字符
            if (table[i] != 0) {
                return false;
            }
        }
        return true;
    }
};

官方解法中给出了另一种写法

class Solution {
public:
    bool isAnagram(string s, string t) {
        if (s.length() != t.length()) {
            return false;
        }
        vector<int> table(26, 0);
        for (auto& ch: s) {              //遍历字符串s
            table[ch - 'a']++;
        }
        for (auto& ch: t) {
            table[ch - 'a']--;
            if (table[ch - 'a'] < 0) {
                return false;
            }
        }
        return true;
    }
};

题目2:349.两个数组的交集

在这里插入图片描述

解法:哈希集合

C++ STL unordered_set容器完全攻略

如果哈希值比较少、特别分散、跨度非常大,使用数组就造成空间的极大浪费
在这里插入图片描述
find(key)查找以值为 key 的元素,如果找到,则返回一个指向该元素的正向迭代器;反之,则返回一个指向容器中最后一个元素之后位置的迭代器(如果 end() 方法返回的迭代器)。

class Solution {
public:
    vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {
        unordered_set<int> result_set;                             //存放结果,unordered_set会自动去重
        unordered_set<int> nums_set(nums1.begin(), nums1.end());   //利用拷贝构造将数组1的元素拷贝到nums_set中
        for (int num : nums2) {                                    //遍历数组2,相当于for(int num;num< nums2.size();num++)
            // 发现nums2的元素 在nums_set里又出现过
            if (nums_set.find(num) != nums_set.end()) {            //unordered_set的find(key)成员方法
                result_set.insert(num);
            }
        }
        return vector<int>(result_set.begin(), result_set.end());
    }
};

题目3:202.快乐数

在这里插入图片描述

解法一:哈希表

根据代码随想录的说法,当遇到了要快速判断一个元素是否出现集合里的时候,就要考虑哈希法了。

解题思路:
输入一个数字,经过不断计算平方和后会有二种情况:1.结果为1,即快乐数;2.进入无限循环。(值不会越来越大,可以自己举几个例子)

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()) {   //如果这个sum曾经出现过,说明已经陷入了无限循环了,立刻return false
                return false;
            }
            else {
                set.insert(sum);     //如果不再哈希集合中则添加这个数
            }
            n = sum;
        }
    }
};

解法二:双指针法

起始就是快慢指针的思想,和题目3:142.环形链表Ⅱ中的快慢指针异曲同工,
解题思路:
定义两个指针fast和slow,fast指针每次移动两个节点,slow指针每次移动一个节点
如果n是一个快乐数,那么fast指针会比slow先达到1;
如果n不是快乐数,那么从某个数开始就会进入无限循环,这里可以理解成一个环形链表,那么fast和slow一定会在同一个数字上相遇。

class Solution {
public:
    //取数值各个位上的单数之和
    int getNext(int n) {
        int sum = 0;
        while (n) {
            sum += (n % 10) * (n % 10);   //%取模(取余数)
            n /= 10;
        }
        return sum;
    }
    bool isHappy(int n) {
        int slow = n;
        int fast = getNext(n);
        while (fast != 1 && slow != fast) {
            slow = getNext(slow);
            fast = getNext(getNext(fast));
        }
        if (fast == 1) {
            return true;
        }
        else{   //slow == fast
            return false;
        }
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
引用中的代码片段是一个递归函数,名为beautifulArray,它接受一个整数n作为参数,并返回一个vector<int>类型的结果。这个函数用于生成一个长度为n的漂亮数组,漂亮数组满足以下条件:如果将其划分为两个任意长度的子数组,那么两个子数组的元素之和不相等。 函数的实现思路是通过递归,将问题划分为两个子问题,然后合并子问题的解。首先判断n是否等于1,如果等于1,则直接返回一个包含1的数组。否则,将n减1后的一半传入递归函数beautifulArray,得到一个漂亮数组res1。然后将n的一半传入递归函数beautifulArray,得到另一个漂亮数组res2。最后,将res1中的每个元素乘以2并减去1,然后与res2中的每个元素乘以2合并到结果数组res中。 引用中的代码片段是一个函数,名为translateNum,它接受一个整数num作为参数,并返回一个整数。这个函数用于计算将整数num翻译成字符串的不同方法数。 函数的实现思路是将整数num转换为字符串str,然后创建一个长度为str.size()-1的动态数组dp,用于记录不同位置的翻译方法数。然后初始化dp和dp[1]为1,表示前两位数字的翻译方法数。接下来,从第三位数字开始遍历字符串str,如果当前数字与前两位数字可以构成一个在10到25之间的整数,则将dp[i]的值设置为dp[i-1]+dp[i-2],表示当前位置的翻译方法数为前一位和前两位数字的翻译方法数之和。最后,返回dp最后一个元素的值,即为翻译整数num的不同方法数。 引用中的代码片段是一个函数,名为numberOfArithmeticSlices,它接受一个vector<int>类型的数组nums作为参数,并返回一个整数。这个函数用于计算数组nums中等差子序列的个数。 函数的实现思路是通过动态规划,创建一个与nums长度相同的动态数组dp,用于记录以每个位置为结尾的等差子序列的个数。然后遍历数组nums,从第三个元素开始,判断当前元素与前两个元素是否构成等差数列,如果是,则将dp[i]的值设置为dp[i-1]加1,表示以当前位置为结尾的等差子序列个数为前一位的等差子序列个数加1。最后,返回dp数组中所有元素的和,即为等差子序列的个数。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值