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

Leetcode-242 有效的字母异位词

这道题的大致思路是开辟一个大小为26的数组来存储字母'a'-'z'的字母数量,先遍历一遍字符串s将s中每个字幕出现的次数记录在该数组中,接着遍历第二个字符串t,将t中字母出现的数量在数组中减去,最后遍历一遍数组检查是否有不为0。在这里有一点需要注意的是题目汇总描述的意思要理清楚,s和t中的每个字母出现的次数是相同的这才叫字母异位词,所以需要检查的条件是数组中的数字不等于零而不是大于零。

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

Leetcode-349 两个数组的交集

这道题我一开始的思路跟上道题一致都是用一个创建的额外的数组来标记每个字符串中元素出现的次数,但这次有点不太一样,有个让我困惑的点是在遍历完成后,有许多额外的点也是符合条件的,就是最后需要求解的点求解比较棘手,因为使用数组的话遇到重复的元素我们需要跳过以便后续的处理,下面是第一次写的代码:

class Solution {
public:
    vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {
        vector<int> a(1005, 0);
        vector<int> count;
        for(int i = 0; i < nums1.size(); i++){
            if(i > 0 && nums1[i - 1] == nums1[i]){
                continue;
            }
            a[nums1[i]]++;
        }
        for(int i = 0; i < nums2.size(); i++){
            if(i > 0 && nums2[i - 1] == nums2[i]){
                continue;
            }
            a[nums2[i]]--;
        }
        for(int i = 0; i < a.size(); i++){
            if(a[i] == 0){
                count.push_back(i);
            }
        }
        return count;
    }
};

出现了两个问题:第一个是去重不彻底:只能对临近的数组元素进行去重操作,若相隔甚远便无法去重,所以解决这个问题我们需要先对数组元素进行排序,再讲排序后的数组进行去重。第二点是:上面代码取的是最后次数被减为0的数组元素,而有很大一部分数组元素并未被加一或减一所以一直保持为0,所以我们需要换个容器,例如用unordered_set容器来存储,该容器可以对重复元素进行去重。

下面是未使用set容器版本的会将重复元素加入到数组中

class Solution {
public:
    vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {
        vector<int> a;
        int hash[1005];
        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){
                a.push_back(nums2[i]);
            }
        }
        return a;
    }
};
class Solution {
public:
    vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {
        unordered_set<int> a;
        int hash[1005];
        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){
                a.insert(nums2[i]);
            }
        }
        return vector<int>(a.begin(), a.end());
    }
};

最后需要注意一点语法规范的问题就是需要返回的是数组,所以我们在最后return的时候需要将这个unordered_set转为int类型的数组。下面是使用set容器的版本:

class Solution {
public:
    vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {
        unordered_set<int> result;
        unordered_set<int> nums(nums1.begin(), nums1.end());
        for(int num:nums2){
            if(nums.find(num) != nums.end()){
                result.insert(num);
            }
        }
        return vector<int>(result.begin(), result.end());
    }
};

这里有几点语法规范比如nums(nums1.begin(), nums1.end())可以直接将nums1的元素输入到nums容器中非常方便快捷。

Leetcode - 202 快乐数

这大体我的思路是用一个while循环,终止条件是num == 1,循环体内部是将n的每位数字的平方加和,但是我遇到的一个困难点是在false的情况下是遇到了与之前num相等的数是就停止循环,突然灵光一闪这里直接用set容器!!每次求出一个num数就将其加入到set容器中,再加入前在判断一下该容器中是否已经存在这个num数如果存在直接返回false。

class Solution {
public:
    bool isHappy(int n) {
        unordered_set<int> nums;
        int num = 0;
        while(num != 1){
            num = 0;
            while(n != 0){
                num += (n % 10) * (n % 10);
                n = n / 10;
            }
            if(nums.find(num) != nums.end()){
                return false;
            }else{
                nums.insert(num);
            }
            n = num;
        }
        return true;
    }
};

Leetcode - 1 两数之和

这道题看的第一眼就想着用暴力解解试试:

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

但时间复杂度达到了O(n^2)就明显太差,这道题用map来写可以大大减少时间复杂度,但这道题对我来说更为重要的是学习map的具体操作和使用:

class Solution {
public:
    vector<int> twoSum(vector<int>& nums, int target) {
        unordered_map<int, int> a;
        for(int i = 0; i < nums.size(); i++){
            if(a.find(target - nums[i]) != a.end()){
                return {a.find(target - nums[i]) -> second, i};
            }
            a.insert(pair<int, int>(nums[i], i));
        }
        return{};
    }
};

return{}括号内可以直接构建一个数组。

今天下午没课就来补一下之前落下的任务;

2024/2/28  16.03 -----magixx

  • 3
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值