Leetcode--------哈希表

Leetcode242. 有效的字母异位词

代码:

class Solution:
    def isAnagram(self, s: str, t: str) -> bool:

        record = [0]*26
        for word_one in s:
            #获取一个字母的相对于字符"a"的ascii码
            record[ord(word_one)-ord("a")] += 1
        for word_two in t:
            #同理
            record[ord(word_two)-ord("a")] -= 1 
        """
        注意:这样不太行,会出现record里面不是所有位置上的元素都是0
        if sum(record) == 0:
            return True
        else:
            return False
        """
        for num in record:
            if num != 0:
                return False
        return True

349. 两个数组的交集

给定两个数组,编写一个函数来计算它们的交集。

示例 1:

输入:nums1 = [1,2,2,1], nums2 = [2,2]
输出:[2]

示例 2:

输入:nums1 = [4,9,5], nums2 = [9,4,9,8,4]
输出:[9,4]
 

说明:

输出结果中的每个元素一定是唯一的。
我们可以不考虑输出结果的顺序。

代码:

class Solution:
    def intersection(self, nums1: List[int], nums2: List[int]) -> List[int]:
        set_result = set()
        set_one = set(nums1)
        for value in nums2:
            #改元素出现在列表一了,就保存起来
            if value in set_one:
                #这里之所以用set,而不是数值因为set会去重
                set_result.add(value)
        return list(set_result)

 202. 快乐数

编写一个算法来判断一个数 n 是不是快乐数。

「快乐数」定义为:

  • 对于一个正整数,每一次将该数替换为它每个位置上的数字的平方和。
  • 然后重复这个过程直到这个数变为 1,也可能是 无限循环 但始终变不到 1。
  • 如果 可以变为  1,那么这个数就是快乐数。

 如果 n 是快乐数就返回 true ;不是,则返回 false 。

思想:

在转变过程,若一个数对应的平方值重复出现了,说明会陷入死循环,这时只要返回False就行。

代码:

class Solution:
    def isHappy(self, n: int) -> bool:
        """
        方法一:超出了时间限制
        """
        # while n <= 2**31:
        #     next_n = 0
        #     #切分这个数,获取每个位置上的数值
        #     for value in str(n):
        #         next_n += int(value)**2
        #     if next_n == 1:
        #         return True
        #     n = next_n
        # return False
        """
        方法二:使用hashmap
        假如在重复变化的过程中,出现一个和重复出现就返回False,
        因为它不能再变为1啦
        """
        sums_set = set()
        while True:
            next_n = 0
            #切分这个数,获取每个位置上的数值
            for value in str(n):
                next_n += int(value)**2
            #已经存在集合中了
            if next_n in sums_set:
                return False
            elif next_n == 1:
                return True
            else:
                sums_set.add(next_n)
                n = next_n

 454. 四数相加 II

给定四个包含整数的数组列表 A , B , C , D ,计算有多少个元组 (i, j, k, l) ,使得 A[i] + B[j] + C[k] + D[l] = 0。

为了使问题简单化,所有的 A, B, C, D 具有相同的长度 N,且 0 ≤ N ≤ 500 。所有整数的范围在 -228 到 228 - 1 之间,最终结果不会超过 231 - 1 。

例如:

输入:
A = [ 1, 2]
B = [-2,-1]
C = [-1, 2]
D = [ 0, 2]

输出:
2

解释:
两个元组如下:
1. (0, 0, 0, 1) -> A[0] + B[0] + C[0] + D[1] = 1 + (-2) + (-1) + 2 = 0
2. (1, 1, 0, 0) -> A[1] + B[1] + C[0] + D[0] = 2 + (-1) + (-1) + 0 = 0

思想:

对前2个数组进行双重for循环遍历,将和放入到一个字典中,字典的key为和,value为该和出现的次数;对后2个数组进行统计,若2个数的和,在字典中存在一个和,使他们的相加为0,就统计其个数。

class Solution:
    def fourSumCount(self, nums1: List[int], nums2: List[int], nums3: List[int], nums4: List[int]) -> int:
        counts = 0
        temp_set = dict()
        for a in nums1:
            for b in nums2:
                value = a+b
                if value in temp_set:
                    temp_set[value] += 1
                else:
                    temp_set[value] = 1
        for c in nums3:
            for d in nums4:
                value = 0-(c+d)
                if value in temp_set:
                    counts += temp_set[value]
        return counts

 383. 赎金信

给定一个赎金信 (ransom) 字符串和一个杂志(magazine)字符串,判断第一个字符串 ransom 能不能由第二个字符串 magazines 里面的字符构成。如果可以构成,返回 true ;否则返回 false。

(题目说明:为了不暴露赎金信字迹,要从杂志上搜索各个需要的字母,组成单词来表达意思。杂志字符串中的每个字符只能在赎金信字符串中使用一次。)

示例 1:

输入:ransomNote = "a", magazine = "b"
输出:false

示例 2:

输入:ransomNote = "aa", magazine = "ab"
输出:false

示例 3:

输入:ransomNote = "aa", magazine = "aab"
输出:true

代码:

class Solution:
    def canConstruct(self, ransomNote: str, magazine: str) -> bool:
        hash_map = dict()
        #用hash_map保存杂志字符串
        for s in magazine:
            if s in hash_map:
                hash_map[s] += 1
            else:
                hash_map[s] = 1
        for s in ransomNote:
            if s in hash_map and hash_map[s] > 0:
                hash_map[s] -= 1
            else:
                return False
        return True

15. 三数之和

给你一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?请你找出所有和为 0 且不重复的三元组。

注意:答案中不可以包含重复的三元组。

示例 1:

输入:nums = [-1,0,1,2,-1,-4]
输出:[[-1,-1,2],[-1,0,1]]

示例 2:

输入:nums = []
输出:[]

示例 3:

输入:nums = [0]
输出:[]

代码:

class Solution:
    def threeSum(self, nums: List[int]) -> List[List[int]]:
        """
        一:hash_map的解法
        时间复杂度太高了
        """

        """
        二:双指针的解法
        在数组中找到3个数,使其和为0
        首先对数组进行排序
        确定第一数为数组的第一个元素,后面n-1个元素中有2个元素使其和为0
        通过2个指针,一个在前一个在后,和大于0,移动后指针,和小于0,移动前指针
        依次遍历第二个元素,那么就后面n-2个元素有2个使其和为0
        """
        if nums == [0]*len(nums) and len(nums) >= 3:
            return [[0]*3]
        result = []
        nums.sort()
        #因为后面至留2个空,放指针
        for i in range(len(nums)):
            if nums[i] > 0:
                break
            if i > 0 and nums[i] == nums[i-1]:
                #和前一个元素相同,这次不比较
                """
                比如[-4,-1,-1,0,1,2]
                第一个-1,会和后面[-1,0,1,2]
                而第二个-1,会和后面[0,1,2],其实,这个比较前面已经比较过了。
                再比较就会重复
                """
                continue
            front = i + 1
            #最后一个位置
            tail = len(nums) - 1
            while front < tail:
                if nums[i]+nums[front]+nums[tail] > 0:
                    #和大了,移动tail
                    tail -= 1
                elif nums[i]+nums[front]+nums[tail] < 0:
                    #和小了,移动front
                    front += 1
                else:
                    #和为0,应该保存这3个位置
                    result_value = [nums[i],nums[front],nums[tail]]
                    result.append(result_value)
                    #这里还要继续比较,注意front下一个元素和taile上一个元素别重复了
                    while front != tail and nums[front] == nums[front+1]:
                        #重复了
                        front += 1
                    while front != tail and nums[tail] == nums[tail - 1]:
                        #重复了
                        tail -= 1
                    front += 1
                    tail -= 1
            #后2个指针碰在一起了
        return result

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值