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

day06:哈希表-242.有效的字母异位词、349.两个数组的交集、202.快乐数、1.两数之和

LeetCode 242.有效的字母异位词

题目链接:

242.有效的字母异位词

文章讲解:

https://programmercarl.com/0242.%E6%9C%89%E6%95%88%E7%9A%84%E5%AD%97%E6%AF%8D%E5%BC%82%E4%BD%8D%E8%AF%8D.html

视频讲解:

https://www.bilibili.com/video/BV1YG411p7BA/

思路和解法:

哈希表:

题目中的字母异位词可以理解为:

两个字符串s和t,如果组成s和t的字母相同,且出现的次数相同,顺序可以不同,那么s和t就是字母异位词。如"abbccc"和"cccbba",两个字符串都由abc组成,虽然组成顺序不同,但是出现的次数一样,那"abbccc"和"cccbbaa"为字母异位词。

题目中说明字符串仅包含小写字母,所以可以考虑数组(数组也是哈希表的一种),数组大小为26,初始化为0。

因为字符a到字符z的ASCII是26个连续的数值,所以字符a映射为下标0,相应的字符z映射为下标25。

所以在遍历的时候,只要将s[i] - 'a’所在的元素做+1操作,t[i] - 'a’所在的元素做-1操作即可。遍历结束后,如果数组里有的数不为0,则说明字符串s和t一定是谁多了或少了,return false,反之return true。

public class Solution {
    public bool IsAnagram(string s, string t) {
        int sl = s.Length, tl = t.Length;
        if(sl != tl)
            return false;
        int[] a = new int[26];
        for(int i = 0; i < sl; i++)
        {
            a[s[i] - 'a']++;
            a[t[i] - 'a']--;
        }

        foreach(var i in a)
        {
            if(i != 0)
                return false;
        }

        return true;
    }
}

LeetCode 349.两个数组的交集

题目链接:

两个数组的交集

文章讲解:

https://programmercarl.com/0349.%E4%B8%A4%E4%B8%AA%E6%95%B0%E7%BB%84%E7%9A%84%E4%BA%A4%E9%9B%86.html

视频讲解:

https://www.bilibili.com/video/BV1ba411S7wu/

思路和解法:

哈希表
采用HashSet解决(虽然题目中限制了两个数组的长度,但是这种类型的题更倾向于用HashSet)

1、将nums1的数值放进哈希表中。

2、再遍历nums2,遍历时,nums2中的每一个元素再去哈希表中去检查是否出现过,出现过,则放进result集合里。

public class Solution {
    public int[] Intersection(int[] nums1, int[] nums2) {
        if(nums1 == null || nums1.Length == 0 || nums2 == null || nums2.Length == 0)
            return new int[0];
        
        HashSet<int> set1 = new HashSet<int>(nums1);
        HashSet<int> set2 = new HashSet<int>(nums2);
        List<int> result = new List<int>();
        foreach(var num in set1)
        {
            if(set2.Contains(num))
            {
                result.Add(num);
            }
        }

        return result.ToArray();
    }
}

LeetCode 202.快乐数

题目链接:

202.快乐数

文章讲解:

https://programmercarl.com/0202.%E5%BF%AB%E4%B9%90%E6%95%B0.html

思路和解法:

哈希表:

题目中提到了可能会无限循环,换而言之,我们为了要避免这种情况,需要把每次的sum存到一个集合里,并判断集合中是否已经存在这个sum,这种快速判断一个元素是否出现在即合理的时候就要考虑哈希表了。

通过对n取余的操作获取到每个位的数并平方求和,然后存储到sum中。

循环结束条件是 n != 1且哈希表中不包含这个sum

public class Solution {
    private int GetSum(int n)
    {
        int sum = 0;
        while(n > 0)
        {
            sum += (n % 10) * (n % 10);
            n /= 10;
        }
        return sum;
    }

    public bool IsHappy(int n) {
        HashSet<int> result = new HashSet<int>();
        while(n != 1 && !result.Contains(n))
        {
            result.Add(n);
            n = GetSum(n);
        }

        return n == 1;
    }
}

LeetCode 1.两数之和

题目链接:

1.两数之和

文章讲解:

https://programmercarl.com/0001.%E4%B8%A4%E6%95%B0%E4%B9%8B%E5%92%8C.html

视频讲解:

https://www.bilibili.com/video/BV1aT41177mK/

思路和解法:

哈希表:

需要一个集合来存放我们遍历过的元素,然后在遍历数组的时候去询问这个集合,某元素是否遍历过,也就是是否出现在这个集合。

public class Solution {
    public int[] TwoSum(int[] nums, int target) {
        Dictionary<int, int> dict = new Dictionary<int, int>();
        for(int i = 0; i < nums.Length; i++)
        {
            if(!dict.ContainsKey(nums[i]))
            {
                dict.Add(nums[i], i);
            }
            int tmp = target - nums[i];
            if(dict.ContainsKey(tmp) && dict[tmp] != i)
            {
                return new int[]{i,dict[tmp]};
            }
        }
        return new int[]{0,0};
    }
}

总结:

遇到哈希表的时,数组、HashSet、HashMap分别在什么时候用

数组:数值比较小,且比较集中(如只有0、5、100000这三个数时,就要开100000长度的数组,空间浪费)

HashSet:没有数值限制,可能有上亿个时

HashMap:在需要用到键值对时采用。即Key-value的存储结构。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值