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

判断一个元素是否出现过的场景 应该第一时间想到哈希法 

242.有效的字母异位词

class Solution {
public:
    bool isAnagram(string s, string t) {
        int arr[26] = {0};
        if (s.size() != t.size())
            return false;
        for (int i = 0; i < s.size(); i++) {
            arr[s[i] - 'a']++;
        }
        for (int i = 0; i < t.size(); i++) {
            arr[t[i] - 'a']--;
        }
        for (int i = 0; i < 26; i++) {
            if (arr[i] != 0)
                return false;
        }
        return true;
    }
};

349. 两个数组的交集

数组

class Solution {
public:
    vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {
        unordered_set<int> result_set;
        int hash[1002] = {0};
        for (int i = 0; i < nums1.size(); i++) {
            hash[nums1[i]] = 1;
        }
        for (int i = 0; i < nums2.size(); i++) {
            if (hash[nums2[i]] == 1) {
                result_set.insert(nums2[i]);
            }
        }
        return vector<int>(result_set.begin(), result_set.end());
    }
};

unordered_set

find(key)查找值为key的元素,如果找到,则返回一个指向该元素的正向迭代器;如果没找到,则返回一个与end()方法相同的迭代器
begin()返回指向容器中第一个元素的正向迭代器
end()返回指向容器中最后一个元素之后位置的正向迭代器返回指向容器中第一个元素的正向迭代器
insert()插入一个新元素
count()计算在无序集合容器中特定元素的出现次数
for(int num : nums2)

for(要遍历的数据类型 遍历变量 : 遍历对象)

从nums2的int型数组中依次将值赋值给num,将num代入for语句代码块中执行

class Solution {
public:
    vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {
        unordered_set<int> result_set;
        unordered_set<int> num_set(nums1.begin(), nums1.end());//无序容器
        for (int num : nums2) {
            if (num_set.find(num) != num_set.end())
                result_set.insert(num);
        }
        return vector<int>(result_set.begin(), result_set.end());
    }
};

202. 快乐数

哈希法

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>result_set; // 若有无限循环,即有值重复出现 考虑哈希法
        while (1) {
            int sum = getSum(n);
            if (sum == 1)
                return true;
            if (result_set.find(sum) !=
                result_set.end()) { // find若没找到则返回end() 此式说明sum重复出现
                return false;
            } 
            else {
                result_set.insert(sum); // 将sum添加到set容器中
            }
            n = sum;
        }
    }
};

快慢指针思想判断循环

“快指针” 每次走两步,“慢指针” 每次走一步,当二者相等时,即为一个循环周期

此时,判断是不是因为 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) {
        int slow = n, fast = n;
        do{
            slow = getSum(slow);
            fast = getSum(fast);
            fast = getSum(fast);
        }while(slow != fast);//使用do..while也很巧妙
        
        return (slow==1)?true:false;//循环有死循环 和1引起的循环 此式判断是否因1循环 
    }
};

1. 两数之和

map

  • iter 是一个迭代器,指向 unordered_map 中的一个元素。
  • iter->first 访问该元素的键(key)。
  • iter->second 访问该元素的值(value)。

unordered_map 提供了一个方法 insert 来将键值对插入到哈希表中。insert 方法有多种重载方式,可以插入单个元素、范围内的元素,或者通过移动插入元素。map.insert(pair<int, int>(nums[i], i)); 是其中一种插入单个元素的方式,使用了 pair 来构造键值对。

class Solution {
public:
    vector<int> twoSum(vector<int>& nums, int target) {
        unordered_map<int, int> map;
        for (int i = 0; i < nums.size(); i++) {
            auto iter = map.find(target - nums[i]);
            if (iter != map.end()) {
                return {iter->second, i};
            }
            map.insert(pair<int, int>(nums[i], i));//是一种插入元素的方式,使用了pair来构造键值对
        }
        return {};
    }
};

 

1.为什么会想到用哈希表?

哈希法适用于查询元素是否出现过,本题可查询 (target-当前元素值) 是否遍历过

2.哈希表为什么用map?

map有key,value,可以查询元素,返回下标。符合题意

3.本题map是用来存什么的?

遍历过的元素

4.map中的key和value用来存什么的?

key存元素,value为对应下标

暴力法

class Solution {
public:
    vector<int> twoSum(vector<int>& nums, int target) {
        for (int i = 0; i < nums.size(); i++) {
            for (int j = i + 1; j < nums.size(); j++) {
                if (nums[i] == (target - nums[j])) {
                    return {i, j};
                }
            }
        }
        return {};
    }
};

  • 12
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值