【Leetcode】top 100 哈希

1 两数之和

给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 target  的那 两个 整数,并返回它们的数组下标。

你可以假设每种输入只会对应一个答案。但是,数组中同一个元素在答案里不能重复出现。

分析:要有一层遍历取 val,问题在于取 target-val 也用遍历会使时间复杂度为O(n^2);

           利用哈希表储存每个数值和其对应的位置,因为仅有target//2可能出现两次(对应一个答案)

class Solution(object):
    def twoSum(self, nums, target):
        """
        :type nums: List[int]
        :type target: int
        :rtype: List[int]
        """
        hashmap = {}
        for i, val in enumerate(nums):
            if (target-val) in hashmap: return[i, hashmap[target-val]]
            else: hashmap[val] = i
        return []
 49 字母异位词分组

给你一个字符串数组,请你将 字母异位词 组合在一起。可以按任意顺序返回结果列表。

字母异位词 是由重新排列源单词的所有字母得到的一个新单词。

分析:构造异位词判断条件和异位词分组结果的哈希表;

           判断条件:字母种类和数量相同

                             1.Counter+sorted—可以简化为sorted

                             2.26位列表统计每个小写字符出现的个数;

from collections import Counter
from collections import defaultdict

class Solution(object):
    def groupAnagrams(self, strs):
        """
        :type strs: List[str]
        :rtype: List[List[str]]
        """
        # hashmap = defaultdict(list)
        hashmap = {}
        for i,val in enumerate(strs):
            count = Counter(val)
            count = tuple(sorted(count.items(), key=lambda num:num[0]))
            hashmap.setdefault(count,[]).append(val)
            # hashmap[count].append(val)

        return list(hashmap.values())

#简化:仅排序字符串作为hashmap.key
class Solution:
    def groupAnagrams(self, strs: List[str]) -> List[List[str]]:
        mp = collections.defaultdict(list)

        for st in strs:
            key = "".join(sorted(st))
            mp[key].append(st)
        
        return list(mp.values())
细节补充

1.哈希表的键存在类型限制:数字、字符串等不可变的类型,或者由数字字符串构成的元组;列表 ×  字典 ×

2.哈希表的值为列表时,插入元素:hashmap.setdefault(key,[]).append(val)

   或者在创建时声明:hashmap = defaultdict(list),hashmap[key].append(val)

3.sort和sorted:sort是list的内置函数,使用方法为list.sort(),实现原地修改的排序;

                          sorted对所有可迭代对象排序,使用方法为sorted(str),会生成一个新的list保存排序结果;

 128 最长连续序列

给定一个未排序的整数数组 nums ,找出数字连续的最长序列(不要求序列元素在原数组中连续)的长度。请你设计并实现时间复杂度为 O(n) 的算法解决此问题。

分析:一层循环遍历数组元素,求以该数值起始的最长序列长度(仅用单变量维护)但由于在求以某个数值起始的最长序列长度时也需要一层循环,不满足题目要求;

优化第二层循环中用到的数组元素就不可能作为起始值,所以可以在进行第二层循环前加入判断条件(前一数值和当前数值不在该数组中),这样数组中的每个数只会进入内层循环一次,时间复杂度满足要求;

class Solution(object):
    def longestConsecutive(self, nums):
        """
        :type nums: List[int]
        :rtype: int
        """
        nums = set(nums)
        maxlen = 0
        for val in nums:
            if (val-1) not in nums:
                num, count = val, 0
                while num in nums:
                    count, num = count+1, num+1
                maxlen = max(maxlen, count)
        return maxlen
  细节补充

1.sorted时间复杂度:O(nlogn)

2.set:无序的不重复集合,相当于没有values的dict,可以用来对list自动去重

#创建集合:
set = set()
#集合自动去重:
new_list = list(set(old_list))    
#增加元素:
1.set.add(val)
2.set.update(val)
#删除元素:
1.set.remove(val)       #元素不存在会发生错误
2.set.discard(val)      #元素不存在不会发生错误
3.set.pop()             #随机删除一个元素
4.set.clear()           #清空
#判断元素是否存在:
val in set
#计算元素个数:
len(set)
#运算:
1.子集or父集:set2.issubset(set1)   #set2是set1的子集,返回bool  
              set1.issuperset(set2)  #set1是set2的父集,返回bool
2.交集:set1 & set2  set = set1.intersection(set2)
3.并集:set1 | set2  set = set1.union(set2)
4.差集:set1 - set2  set = set1.difference(set2)
5.异或:set1 ^ set2  set = set1.symmetric_difference(set2)

3.查找元素的时间复杂度:set—O(1)list—O(n)

python list/tuple/dict/set/deque的简单比较、优化和时间复杂度(表格)_python list和tuple的查找元素时间复杂度-CSDN博客

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值