代码随想录算法训练营Day6|242有效字母异位、349求两个数组的交集、

1.3leetcode242有效字母异位

这题在开营前琢磨过,复习了一下,leetcode上记了笔记,就直接抄过来了

第一次解答忘记了在判断长度是否相等后,长度不相等可以直接返回false,不需要往下判断了。

没通过的原因,有部分是因为不熟悉C++的使用,一些功能不知道怎么调用。

最简单的办法是暴力破解,用双重循环遍历,同时记录下相同字母的字母数量,时间复杂度是O(n^2).

看了其他人的题解得到的收获:

收获1(用排序去解)

先排序再判断长度,长度不等就false.

收获2(定义数组的方法)

定义数组的方法可以是,将字符串以每个字符分别放进数组

char[]str1 = s.toCharArray();
char[]str2 = t.toCharArray();

其中的s是一个已知的字符串。

数组排序可以是直接用Array.sort函数对数组str1和数组str2进行排序

Array.sort(str1);
Array.sort(str2);

[用哈希表求解思路]

哈希表的本质是数组,我们就定义一个大小为26的数组,对应值初始化为0,用来记录每个小写字母出现的次数,先遍历s当该字母出现一次就+1,再遍历,出现一次就-1,最后判断是否都为0,如果是,那么s和t就是彼此的异位字母。

[收获4]

使用数组元素对字母进行计数时,考虑用当前字母的ASCII码减去‘a’,也就是减去96,这样可以得到26个小写字母从0--25的索引所对应的位置,可以节省空间。

int record[26]={0};
for(int i=0;i<s.length();i++)
{
 record[s[i]-'a']+=1;
}

[收获5]

判断两个字符串是否相等可以使用函数Array.equals

返回值是bool型,可能是false或true.

Arrays.equals(str1,str2);

完整求解代码:

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

2.两个数组的交集

set

使用数组做哈希表是因为题目限制了数值的大小,当不再限制数值的大小时,就无法使用数组来做哈希表。如果哈希值比较小、特别分散、跨度很大,就会造成数组空间浪费。这时选择set.

set在C++中有3种可用的数据结构,std::set  ;   std::multiset  ;   std::unordered_set  ;

std::set和std::multiset底层实现是红黑树,std::unordered_set的底层实现是哈希表。

[题目思路]

这题使用std::unordered_set,它读写效率最高,无需排序,数据不重复。

这题不涉及太复杂的算法,只要用一个循环遍历,找出同时出现在num1和num2中的数即可。用set是为了使数据不重复。

将一个普通数组转化成unordered_set 形式,使用nums_set(Arrays.begin(),Arrays.end());

unordered_set<int>nums_set(nums1.begin(),nums1.end());//将数组nums1变成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());
     for(int num:nums2)
     {
         if(nums_set.find(num) !=nums_set.end()){
             result_set.insert(num);
         }
     }
     return vector<int>(result_set.begin(),result_set.end());
    }
};

set的直接使用不仅空间比数组大,而且速度比数组慢,set把数值映射到key上都要做hash计算的。在数量大的情况下,差异会很显著。

3.202快乐数

原题链接leetcode202快乐数

[哈希法求解]

题目要求将正整数的每位的数字平方求和,有和为1就true,无则继续找,至sum重复出现,false.

可以写一个函数对数值各个位上的单数之和进行求解

int getSum(int n){
  int sum = 0;
  while(n){
    sum += (n % 10)*(n % 10);//对一个整数取余,得到的是个位数
    n/=10;
    }
  return sum;
 }

使用set求解,设置一个unordered_set的容器set,只要判断出当前的sum不在set里,就将这个sum通过insert()函数添加到set,每得到一个sum,就执行一次判断,直到出现和set容器内存放的值相等的sum,就返回false.结束循环,这种方式来判断sum是否重复出现。

unordered_set<int>set;
while(1){
int sum = getsum(n);//调用getsum()求sum的函数
   if(sum == 1){
     return true;
     }
  if(set.find(sum) != set.end()){
  return false; //重复了,直接返回false
  }else{
    set.insert(sum);//将没有重复的sum插入进set
  }
 n = sum;
}

完整求解代码如下:

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()){
            return false;
        }else{
            set.insert(sum);
        }
        n=sum;
    }
    }
};

两数之和

原题链接:1.两数之和

[关于map]map分三种,std::map和std::mutimap底层是红黑树,std::unoredered_map底层是哈希表。

map有两个值value和key,value是数组元素下标,key是数组元素。

遍历数组时,向map去查询是否有与当前被遍历到的元素相同的数值,有,就找到对应的key和value,没有就把这个被遍历到的元素放进map,这里和前一个题目unordered_set的set思路一样。

在定义mao时记得map中是key和value两个值,所以应用<int,int>

std::unordered_map<int,int>map;

对数组遍历,找和map中某个元素相同的元素,如果有就返回value和key,如果没有,就把它的value,key通过insert()函数记录进map。

map.insert(pair<int,int>(nums[i],i));

完整求解代码如下:

class Solution {
public:
    vector<int> twoSum(vector<int>& nums, int target) {
        std::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));
        }
        return{};
    }
};

  • 20
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
代码随想录算法训练营是一个优质的学习和讨论平台,提供了丰富的算法训练内容和讨论交流机会。在训练营中,学员们可以通过观看视频讲解来学习算法知识,并根据讲解内容进行刷题练习。此外,训练营还提供了刷题建议,例如先看视频、了解自己所使用的编程语言、使用日志等方法来提高刷题效果和语言掌握程度。 训练营中的讨论内容非常丰富,涵盖了各种算法知识点和解题方法。例如,在第14天的训练营中,讲解了二叉树的理论基础、递归遍历、迭代遍历和统一遍历的内容。此外,在讨论中还分享了相关的博客文章和配图,帮助学员更好地理解和掌握二叉树的遍历方法。 训练营还提供了每日的讨论知识点,例如在第15天的讨论中,介绍了层序遍历的方法和使用队列来模拟一层一层遍历的效果。在第16天的讨论中,重点讨论了如何进行调试(debug)的方法,认为掌握调试技巧可以帮助学员更好地解决问题和写出正确的算法代码。 总之,代码随想录算法训练营是一个提供优质学习和讨论环境的平台,可以帮助学员系统地学习算法知识,并提供了丰富的讨论内容和刷题建议来提高算法编程能力。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [代码随想录算法训练营每日精华](https://blog.csdn.net/weixin_38556197/article/details/128462133)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值