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

242. 有效的字母异位词

题目链接:力扣

看到题目的第一想法:

看了carl哥的哈希表讲解,做这道题还算很简单的,注意其中的ASCII码转换对应其下标就可以很好地解决这道题目了,这题也是使用数组作为哈希表的经典题目了

class Solution {
public:
    bool isAnagram(string s, string t) {
        // 基本思想:使用哈希表,先将s字符串中的各个字母减去a的ASCII码,然后加在hash对应的下标
        // 然后用相同的方法减去t字符串的各个对应ASCII码即可
        if(s.size() != t.size()) return false;
        int hash[26] = {0};
        for(int i = 0; i < s.size(); i++) {
            hash[s[i] - 'a']++;
        }
        for(int i = 0; i < t.size(); i++) {
            hash[t[i] - 'a']--;
        }
        // 判断,若有非零项表示非有效的字母异位词
        for(int i = 0; i < 26; i++) {
            if(hash[i] != 0) return false;
        }
        // 全部为零说明是有效的字母异位词,返回true
        return true;
    }
};

遇到的问题:

暂时没有什么大问题,可以单独ac

349. 两个数组的交集

题目链接:力扣

看见题目的第一想法:

这道题一开始想到了暴力,但这样时间复杂度达到了n方,这肯定不合理,这使就要使用别的方法,比如哈希表就能很好的解决这个问题,但是题目给出了值小于1000,这样就可以用数组作为哈希表了,但是若没有这个条件,我们可以用另外一种数据结构:集合set来作为哈希表来解决这个问题,具体使用unordered_set这种集合,因为我们不需要数据有序,且可以去重,这算是更优解,下面给出2种解答方法

class Solution {
public:
    vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {
        // 数组实现
​
        int nums[1001] = {0};
        // 用来存放结果,set为了去重
        unordered_set<int> result;
        for(int i = 0; i < nums1.size(); i++) {
            nums[nums1[i]]++;
        }
        for(int i = 0; i < nums2.size(); i++) {
            if(nums[nums2[i]] != 0) result.insert(nums2[i]);
        }
        return vector<int>(result.begin(),result.end());
    }
};

class Solution {
public:
    vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {
        // unordered_set实现
        
        // 基本思路:使用set实现哈希表,先把nums1存入unorder_set里面,做到存放查找数据高效且去重
        // 然后逐一将num_set和nums2做比对,相等放入result中(result也为unordered_map,主要是去重),result即为两个数组的交集
​
        // 存放结果,达到去重效果
        unordered_set<int> result;
        // 存放nums1存入set中的值
        unordered_set<int> num_set(nums1.begin(), nums1.end());
        
        // 将num1存入num_set
        for(int num : nums1) {
            num_set.insert(num);
        }
​
        // 比对num_set和nums2中是否相等,相等存入result
        for(int num : nums2) {
            if(num_set.count(num)) {
                result.insert(num);
            }
        }
        return vector<int>(result.begin(), result.end());
    }
};

遇到的问题:

主要是对于set这种数据结构的操作不太熟悉,去学习了一下有关set的使用方法,思维来说没太大的问题

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) {
​
        // 基本思路:由于若不是快乐数的话会无限循环且不会为1,说明到某个数一定会重复,且不为1
        // 这样就可以用哈希表来存放这些数据,若重复出现返回false,若找到1就返回true
​
        // 定义一个存放数字平方和的set,可以统计是否出现
        unordered_set<int> un_set;
        while(true) {
            int sum = getSum(n);
            if(sum == 1) return true;
            // 重复返回false
            if(un_set.count(sum)) break;;
            un_set.insert(sum);
            n = sum;
        }
        return false;
    }
};

遇到的问题:

没太大的问题

1. 两数之和

题目链接:力扣

看到题目的第一想法:

这题一看就比较难以解决,算是小白噩梦了,做到哈希表这一章就自动的想到了使用哈希表实现,由于之前学过哈希表,看到这题已经大概有了思路,接下来就是用什么哈希表来实现,一开始发现结果需要存放数组数据还有其下标,前面两种方法虽然可以实现,但需要将每个元素存放为一个小的数组,比较麻烦,这时候就可以使用哈希表的第三种结构:map,但对这种结构不太熟悉,又去学习了一些关于map的使用方法才来解决这个题,但在实现的时候还是有小问题

class Solution {
public:
    vector<int> twoSum(vector<int>& nums, int target) {
        // 基本思路:定义一个map类型的哈希表,用来装nums与target的差值,然后往后遍历,若发现新遍历的值
        // 在哈希表里面,说明两数相加为target,返回值即可
        unordered_map<int, int> un_map;
        vector<int> res;
        for(int i = 0; i < nums.size(); i++) {
            auto iter = un_map.find(nums[i]);
            if(iter != un_map.end()) {
                return {iter->second, i};
            }
            un_map.insert(pair(target-nums[i], i));
        }
        return {};
    }
};

遇到的困难:

主要的困难是在实现上,一开始写的很乱,虽然思路是正确的但由于对map不熟悉或者说是对map的各项关于算法的操作不熟悉,一开始没能很好的写出来,后来看了carl的题解写的非常简洁,然后算是借鉴了这种方法来实现的我自己的思路,总体来说还不错

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
第二十二天的算法训练营主要涵盖了Leetcode目中的三道目,分别是Leetcode 28 "Find the Index of the First Occurrence in a String",Leetcode 977 "有序数组的平方",和Leetcode 209 "长度最小的子数组"。 首先是Leetcode 28目要求在给定的字符串中找到第一个出现的字符的索引。思路是使用双指针来遍历字符串,一个指向字符串的开头,另一个指向字符串的结尾。通过比较两个指针所指向的字符是否相等来判断是否找到了第一个出现的字符。具体实现的代码如下: ```python def findIndex(self, s: str) -> int: left = 0 right = len(s) - 1 while left <= right: if s[left == s[right]: return left left += 1 right -= 1 return -1 ``` 接下来是Leetcode 977目要求对给定的有序数组中的元素进行平方,并按照非递减的顺序返回结果。这里由于数组已经是有序的,所以可以使用双指针的方法来解决问。一个指针指向数组的开头,另一个指针指向数组的末尾。通过比较两个指针所指向的元素的绝对值的大小来确定哪个元素的平方应该放在结果数组的末尾。具体实现的代码如下: ```python def sortedSquares(self, nums: List[int]) -> List[int]: left = 0 right = len(nums) - 1 ans = [] while left <= right: if abs(nums[left]) >= abs(nums[right]): ans.append(nums[left ** 2) left += 1 else: ans.append(nums[right ** 2) right -= 1 return ans[::-1] ``` 最后是Leetcode 209目要求在给定的数组中找到长度最小的子数组
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值