LeetCode刷题1:第三周

LeetCode刷题1:第三周


相关系列笔记:
LeetCode刷题:前言
LeetCode刷题1:第一周
LeetCode刷题1:第二周
LeetCode刷题1:第三周
LeetCode刷题1:第四周
LeetCode刷题1:第五周
LeetCode刷题1:第六周
LeetCode刷题1:第七周

前言

  week3 Topic:哈希表,题目列表如下
    (1) 202.快乐数
    (2) 217.存在重复元素
    (3) 49.字母异位词分组
    (4) 36.有效的数独
    (5) 347.前K个高频元素

知识点

  散列表(也叫哈希表) 是一种数据结构,其数据元素的地址或索引值由散列函数生成。 这使得访问数据的速度更快,因为索引值是数据值的关键字。 换句话说,哈希表存储键值对,但键是通过哈希函数生成的。

  因此,数据元素的搜索和插入函数变得更快,因为键值本身成为存储数据的数组的索引。

  在Python中,字典数据类型表示哈希表的实现。字典中的键满足以下要求。

  • 字典的键是可散列的,即通过散列函数生成该散列函数,该散列函数为提供给散列函数的每个唯一值生成唯一结果。
  • 字典中数据元素的顺序不固定。

  哈希函数是一个可以将任意长度的数据块映射到固定长度的值,这个步骤称为hash,也就是散列

  hash 函数有三个主要的特征:

  1. 计算迅速:计算一个数据块的hash值非常快
  2. 确定性:相同用字符串会产生相同的hash值
  3. 结果固定长度:不管输入的是,一个字节还是十个字节,或者上万个字节,结果总是预先确定的长度。

  另一个特征在hash函数中非常普遍,即他们是单方向的:通过函数实现后,原始数据丢失了,我们可以通过字符串得到一个hash值,但不能通过一个hash也就是散列得到原始的字符串(因为有对数据降维的方法会造成数据的丢失)。这种特性并不是对所有hash函数的强制性规定,但是当需要加密安全时,这种性质还是挺好用的。

  一些比较受欢迎的算法包括:MD5、SHA-1、SHA-2,NTLM

  所以可通过使用下面的字典数据类型来看到哈希表的实现。

在字典中访问值

  要访问字典元素,可以使用熟悉的方括号 [] 来获取它的值。

# Declare a dictionary 
dict = {'Name': 'maxsu', 'Age': 27, 'Class': 'First'}

# Accessing the dictionary with its key
print ("dict['Name']: ", dict['Name'])
print ("dict['Age']: ", dict['Age'])

  执行上面示例代码,得到以下结果

dict['Name']:  maxsu
dict['Age']:  27
Shell

更新字典元素

  可以通过添加新条目或键值对,修改现有条目或删除现有条目来更新字典,如简单示例中所示 -

# Declare a dictionary
dict = {'Name': 'Maxsu', 'Age': 26, 'Class': 'First'}
dict['Age'] = 8; # update existing entry
dict['School'] = "第一中学"; # Add new entry
print ("dict['Age']: ", dict['Age'])
print ("dict['School']: ", dict['School'])

  执行上面示例代码,得到以下结果

dict['Age']:  8
dict['School']:  第一中学
Shell

删除字典元素

  可以删除单个字典元素,也可以清除字典的全部内容。 也可以在一个操作中删除整个字典。 要显式删除整个字典,只需使用del语句。 参考以下代码 :

dict = {'Name': 'Maxsu', 'Age': 26, 'Class': 'First'}
del dict['Name']; # remove entry with key 'Name'
dict.clear();     # remove all entries in dict
del dict ;        # delete entire dictionary

print ("dict['Age']: ", dict['Age'])
print ("dict['School']: ", dict['School'])
Python

  请注意,由于在执行del语句之后,字典不再存在之后会引发异常。

LeetCode例题

202. 快乐数

  编写一个算法来判断一个数 n 是不是快乐数
  「快乐数」定义为:对于一个正整数,每一次将该数替换为它每个位置上的数字的平方和,然后重复这个过程直到这个数变为 1,也可能是 无限循环 但始终变不到 1。如果 可以变为 1,那么这个数就是快乐数。
  如果 n 是快乐数就返回 True ;不是,则返回 False 。
     示例:
      输入:19
      输出:true
    解释:
      1^2 + 9^2 = 82
      8^2 + 2^2 = 68
      6^2 + 8^2 = 100
      1^2 + 0^2 + 0^2 = 1

  实现
在这里插入图片描述

class Solution:
    def isHappy(self, n: int) -> bool:
        already = set()
        while n != 1:
            if n in already:
                return False
            already.add(n)
            n = sum([int(x) * int(x) for x in str(n)])
        return True

在这里插入图片描述

217. 存在重复元素

  给定一个整数数组,判断是否存在重复元素
    如果任意一值在数组中出现至少两次,函数返回 true 。如果数组中每个元素都不相同,则返回 false 。
       示例 1:
        输入: [1,2,3,1]
        输出: true
      示例 2:
        输入: [1,2,3,4]
        输出: false
      示例 3:
        输入: [1,1,1,3,3,4,3,2,4,2]
        输出: true

  实现
在这里插入图片描述

  首先set(nums),集合会直接删除重复元素
  然后判断集合是否和列表等长,等长返回False 不等长说明有重复数,返回True

class Solution:
    def containsDuplicate(self, nums: List[int]) -> bool:
        # set(nums)直接删除重复元素
        # 判断集合是否和列表等长
        return not len(nums) == len(set(nums))

在这里插入图片描述

49. 字母异位词分组

  给定一个字符串数组,将字母异位词组合在一起。字母异位词指字母相同,但排列不同的字符串
    示例:
      输入: [“eat”, “tea”, “tan”, “ate”, “nat”, “bat”]
      输出:
        [
         [“ate”,“eat”,“tea”],
         [“nat”,“tan”],
         [“bat”]
        ]

  实现
在这里插入图片描述

class Solution:
    def groupAnagrams(self, strs: List[str]) -> List[List[str]]:
        dic = {} 
        res = []
        # 把每个字符串分类
        # 排序字符串变成列表再转成字符串
        for word in strs:
            dic.setdefault(str(sorted(word)),[]).append(word)
        for val in dic.values():
            res.append(val)
        return res

在这里插入图片描述

36. 有效的数独

  判断一个 9x9 的数独是否有效。只需要根据以下规则,验证已经填入的数字是否有效即可
    1. 数字 1-9 在每一行只能出现一次。
    2. 数字 1-9 在每一列只能出现一次。
    3. 数字 1-9 在每一个以粗实线分隔的 3x3 宫内只能出现一次。
在这里插入图片描述
    上图是一个部分填充的有效的数独。
    数独部分空格内已填入了数字,空白格用 ‘.’ 表示。
      示例 1:
        输入:
          [
           [“5”,“3”,".",".",“7”,".",".",".","."],
           [“6”,".",".",“1”,“9”,“5”,".",".","."],
           [".",“9”,“8”,".",".",".",".",“6”,"."],
           [“8”,".",".",".",“6”,".",".",".",“3”],
           [“4”,".",".",“8”,".",“3”,".",".",“1”],
           [“7”,".",".",".",“2”,".",".",".",“6”],
           [".",“6”,".",".",".",".",“2”,“8”,"."],
           [".",".",".",“4”,“1”,“9”,".",".",“5”],
           [".",".",".",".",“8”,".",".",“7”,“9”]
          ]
        输出: true
      示例 2:
        输入:
          [
           [“8”,“3”,".",".",“7”,".",".",".","."],
           [“6”,".",".",“1”,“9”,“5”,".",".","."],
           [".",“9”,“8”,".",".",".",".",“6”,"."],
           [“8”,".",".",".",“6”,".",".",".",“3”],
           [“4”,".",".",“8”,".",“3”,".",".",“1”],
           [“7”,".",".",".",“2”,".",".",".",“6”],
           [".",“6”,".",".",".",".",“2”,“8”,"."],
           [".",".",".",“4”,“1”,“9”,".",".",“5”],
           [".",".",".",".",“8”,".",".",“7”,“9”]
          ]
        输出: false
      解释: 除了第一行的第一个数字从 5 改为 8 以外,空格内其他数字均与 示例1 相同。
       但由于位于左上角的 3x3 宫内有两个 8 存在, 因此这个数独是无效的。

  实现
在这里插入图片描述

class Solution:
    def isValidSudoku(self, board: List[List[str]]) -> bool:
        def isvaild9(lyst):
            nums = list(filter(lambda x:x != '.', lyst))
            return len(set(nums)) == len(nums)
        
        for row in board:# 行
            if not isvaild9(row):
                return False
        
        for column in zip(*board):# 列
            if not isvaild9(column):
                return False
        
        for row in range(3):# 3*3宫格
            for column in range(3):
                tmp = [board[i][j] for i in range(row*3, row*3+3) for j in range(column*3, column*3+3)]
                if not isvaild9(tmp):
                    return False
        return True

在这里插入图片描述

347. 前 K 个高频元素

  给定一个非空的整数数组,返回其中出现频率前 k 高的元素
     示例 1:
       输入: nums = [1,1,1,2,2,3], k = 2
       输出: [1,2]
    示例 2:
       输入: nums = [1], k = 1
       输出: [1]
     提示:
       • 你可以假设给定的 k 总是合理的,且 1 ≤ k ≤ 数组中不相同的元素的个数。
       • 你的算法的时间复杂度必须优于 O(n log n) , n 是数组的大小。
       • 题目数据保证答案唯一,换句话说,数组中前 k 个高频元素的集合是唯一的。
       • 你可以按任意顺序返回答案。

  实现
在这里插入图片描述

  直接counter,然后对生成的字典排序取前k个即可,时间复杂度为nlogn

class Solution:
    def topKFrequent(self, nums: List[int], k: int) -> List[int]:
        # counter,对生成的字典排序取前k个
        dic = Counter(nums)
        res = sorted(dic.items(), key=lambda item:item[1], reverse=True)
        return list(map(lambda x:x[0], res))[:k]

在这里插入图片描述

评论 4 您还未登录,请先 登录 后发表或查看评论

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

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
©️2022 CSDN 皮肤主题:技术黑板 设计师:CSDN官方博客 返回首页

打赏作者

南有芙蕖

你的鼓励将是我最大的动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值