第六天| 242.有效的字母异位词 、 349. 两个数组的交集 、 202. 快乐数、1. 两数之和

Leetcode 242.有效的字母异位词

题目链接:242 有效的字母异位词

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

  • 你可以假设字符串只包含小写字母。

思考一:使用哈希表map来存储键值对,先遍历字符串s,将其中的字符和字符出现次数以键值对的格式存入map中。再遍历字符串t,每次循环将map中对应字符的值减一,若处理后的值为0则删除该键值对,若出现map中不存在的字符则返回false

代码: 

class Solution {
public:
    bool isAnagram(string s, string t) {
        unordered_map maps;

        //分类好字符串s的内容
        for (char m : s) {
            if (maps.find(m) != maps.end())
                maps[m]++;
            else
                maps[m] = 1;
        }

        //按字符串t来删除元素
        for (char m : t) {
            if (maps.find(m) == maps.end())      //出现不存在的字符
                return false;
            maps[m]--;
            if (maps[m] == 0)        //字符对应次数为0时删除
                maps.erase(m);
        }
        return maps.empty();
    }
};

思考二:因为字符a到字符z的ASCII是26个连续的数值,所以可用长度为26的数组record来存储每个字符出现的次数,字符a映射为下标0,相应的字符z映射为下标25。

  • 在遍历字符串s的时只需要将 s[i] - ‘a’ 所在的元素做+1 操作即可,并不需要记住字符a的ASCII,只要求出一个相对数值就可以了。
  • 在遍历字符串t的时候,对t中出现的字符映射哈希表索引上的数值再做-1的操作。
  • 最后检查一下,record数组如果有的元素不为零0,说明字符串s和t一定是谁多了字符或者谁少了字符

代码:

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

Leetcode 349. 两个数组的交集

题目链接:349 两个数组的交集

题干:给定两个数组,编写一个函数来计算它们的交集。

  •  输出结果中的每个元素一定是唯一的。 我们可以不考虑输出结果的顺序。

思考:使用哈希表set来存储数字,先将数组nums1中元素全部存入nums_set容器中。再遍历数组nums2,将存在交集的数字存入result_set容器中。最后把set转成vector

代码:

class Solution {
public:
    vector intersection(vector& nums1, vector& nums2) {
        unordered_set result_set; // 存放结果,之所以用set是为了给结果集去重
        unordered_set 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(result_set.begin(),result_set.end());
    }
};

Leetcode 202. 快乐数

题目链接:202 快乐数

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

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

思考一:本题的关键在于如何判断操作进入无限循环,可以通过判断一次操作后的结果是否曾经出现过

代码:

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 set;
        while (n != 1) {
            int sum = getSum(n);
            //sum出现过则开始循环
            if (set.find(sum) != set.end()) 
                return false;
            else
                set.insert(sum);

            n = sum;
        }
        return true;
    }
};

思考二:还可以通过双指针法,快指针进行两次操作,慢指针进行一次操作,若快慢指针值相等则进入循环

代码:

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) {
        int fast = n,slow = n;
        while (fast != 1 && slow != 1) {
            //快指针操作两次,慢指针操作一次
            fast = getSum(fast);
            fast = getSum(fast);
            slow = getSum(slow);

            if (fast == slow && fast != 1)//快慢指针相同且不为1
                return false;
        }
        return true;
    }
};

Leetcode 1. 两数之和

题目链接:1 两数之和

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

  • 你可以假设每种输入只会对应一个答案。但是,数组中同一个元素不能使用两遍。

思考:使用哈希表map来存储键值对,键为数组内元素,值为元素在数组中的下标。循环遍历数组,每次在map中寻找匹配的元素,若存在返回两下标,反之将数组元素以及下标以键值对的形式存入map(暴力法:两层for循环)

代码:

class Solution {
public:
    vector twoSum(vector& nums, int target) {
        unordered_map map;

        for (int i = 0; i < nums.size(); i++) {
            auto it = map.find(target - nums[i]);
            if (it != map.end())        //匹配成功
                return {it->second,i};
            
            map.insert(pair(nums[i],i));       //匹配失败的元素存入容器内
        }
        return {};
    }
};

自我总结:

  • 判断元素是否出现过,第一时间考虑是否能用哈希表来处理
  • 判断是否处于死循环,可以通过双指针法

你可能感兴趣的:(代码随想录算法训练营,哈希算法,算法,leetcode)