C++刷题笔记

C++刷题笔记,第1张

哈希表理论基础

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容器完全攻略

如果哈希值比较少、特别分散、跨度非常大,使用数组就造成空间的极大浪费

class Solution {
public:
    vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {
        unordered_set<int> result_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;
        }
    }
};

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/756141.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-04-30
下一篇 2022-04-30

发表评论

登录后才能评论

评论列表(0条)

保存