中等难度-哈希表

  • 来源于leetcode题库49,347,438,560,739

49.字母异位词分组

  • 题目描述
    • 给定一个字符串数组,将字母异位词组合在一起。字母异位词指字母相同,但排列不同的字符串。
  • 示例

输入: ["eat", "tea", "tan", "ate", "nat", "bat"]
输出:
[
["ate","eat","tea"],
["nat","tan"],
["bat"]
]

  • 题解
class Solution:
    def groupAnagrams(self, strs: List[str]) -> List[List[str]]:
        dict = {}
        for item in strs:
            # 字典的键必须是不可变类型,所以用tuple
            key = tuple(sorted(item))
            # 如果找不到则返回默认值[],即把字符串排序后作为键
            # 把能排序成键的字符串作为值存起来
            dict[key] = dict.get(key, []) + [item]
        return list(dict.values())



347.前k个高频元素

  • 题目描述:
    • 给定一个非空的整数数组,返回其中出现频率前 k 高的元素。
  • 示例:

示例 1:
输入: nums = [1,1,1,2,2,3], k = 2
输出: [1,2]
示例 2:
输入: nums = [1], k = 1
输出: [1]

  • 题解:
class Solution:
    def topKFrequent(self, nums: List[int], k: int) -> List[int]:
        dit={}                            
        for i in nums:
            #如果不存在,则将其存入字典中,此时该值的出现频率为1
            if i not in dit:     
                dit[i] = 1
            #如果已经存在,则其出现频率加1
            else:                
                dit[i] =  dit[i]+1
        #由于字典无法排序,因此需要先将字典转换为列表,列表中的每一个元素为 键-值 构成的元祖
        temp = []         
         #使用字典的items函数,获取 键-值对元祖列表            
        for item in dit.items():  
            #这里需要对出现频率进行排序,因此将每一个元祖元素进行转置,
            #即出现次数在前,字符在后
            temp.append(item[::-1])    
        #对列表进行排序,对于每一个元素都是元祖的列表来说,
        #其排序是按照元祖的第一个元素进行的
        temp.sort(reverse=True)       
        #使用列表推导式求前k个高频元素,因为转置过,所以元素在后,为temp[i][1]
        return [temp[i][1] for i in range(k)]  
   


438. 找到字符串中所有字母异位词

  • 题目描述

    • 给定一个字符串 s 和一个非空字符串 p,找到 s 中所有是 p 的字母异位词的子串,返回这些子串的起始索引。
      字符串只包含小写英文字母,并且字符串 s 和 p 的长度都不超过 20100。
  • 示例

示例 1:
输入:
s: "cbaebabacd" p: "abc"
输出:
[0, 6]
解释:
起始索引等于 0 的子串是 "cba", 它是 "abc" 的字母异位词。
起始索引等于 6 的子串是 "bac", 它是 "abc" 的字母异位词。
示例 2:
输入:
s: "abab" p: "ab"
输出:
[0, 1, 2]
解释:
起始索引等于 0 的子串是 "ab", 它是 "ab" 的字母异位词。

起始索引等于 1 的子串是 "ba", 它是 "ab" 的字母异位词。
起始索引等于 2 的子串是 "ab", 它是 "ab" 的字母异位词。

  • 题解:
class Solution:
    def findAnagrams(self, s: str, p: str) -> List[int]:
         # 记录p, s字母个数
        p_count = [0] * 26
        s_count = [0] * 26
        res = []
        # 非空字符串p的所有字母
        for a in p:
            p_count[ord(a) - 97] += 1
        # 左指针
        left = 0
        for right in range(len(s)):
            # 如果右指针小于p的长度-1,即左右指针之间的字母数量比p少,不可能是异位词
            if right < len(p) - 1:
                s_count[ord(s[right]) - 97] += 1
                continue
            # 窗口加一个, 减一个,维护长度为len(p)的长度
            s_count[ord(s[right]) - 97] += 1
            if p_count == s_count:
                res.append(left)
            # 左指针位置+1
            s_count[ord(s[left]) - 97] -= 1
            left += 1
        return res



560.和为k的子数组

  • 题目描述:
    • 给定一个整数数组和一个整数 k,你需要找到该数组中和为 k 的连续的子数组的个数。
  • 示例:

输入:nums = [1,1,1], k = 2
输出: 2 , [1,1] 与 [1,1] 为两种不同的情况。

  • 题解:
class Solution:
    def subarraySum(self, nums: List[int], k: int) -> int:
        d = {} # 哈希表   '前缀和:出现次数'
        # acc为前缀和,count为出现次数
        acc = count = 0
        for num in nums:
            # 前缀和
            acc += num
            # 如果为k,则count+1
            if acc == k:
                count += 1
            # 如果acc-k在哈希表中,则将acc-k对应的次数加上去
            if acc - k in d:
                count += d[acc-k]
            # 如果前缀和acc已经在哈希表中了那次数+1
            if acc in d:
                d[acc] += 1
            # 否则将其加入到哈希表中
            else:
                d[acc] = 1
        return count


739.每日温度

  • 题目描述
    • 请根据每日 气温 列表,重新生成一个列表。对应位置的输出为:要想观测到更高的气温,至少需要等待的天数。如果气温在这之后都不会升高,请在该位置用 0 来代替。
  • 示例:

给定一个列表 temperatures = [73, 74, 75, 71, 69, 72, 76, 73],你的输出应该是 [1, 1, 4, 2, 1, 1, 0, 0]。

  • 题解
class Solution:
    def dailyTemperatures(self, T: List[int]) -> List[int]:
        l = len(T)
        stack = []  
        # 所以这里初始化一个全是0的list,因为题目中说没有匹配的就返回0,
        res = [0] * l   

        for idx, t in enumerate(T):
            # 当stack为空时,运行stack.append(idx),则stack=[0]
            # 然后仅当遍历元素 t 小于stack顶端的值时append进去,
            # 这会导致stack中idx代表的元素是单调递减的!!!!
            # 如果此时遍历到一个 t,大于stack顶端的值,那这个t就是离stack
            # 顶端值最近的那个大值。
            while stack and t > T[stack[-1]]:  
                # 然后pop出来,还是要注意stack.pop出来的是idx,这样res这
                # 一串0里对应位置的0就会被替换成应有的值。                           
                # 再进入while循环判断t和stack.pop后的新的顶端值哪个大。
                # 如此反复。
                res[stack.pop()] = idx-stack[-1] #下标之差就是等待的天数
            stack.append(idx)
        return res

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 200,045评论 5 468
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 84,114评论 2 377
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 147,120评论 0 332
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,902评论 1 272
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,828评论 5 360
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,132评论 1 277
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,590评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,258评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,408评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,335评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,385评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,068评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,660评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,747评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,967评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,406评论 2 346
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,970评论 2 341