基础数据结构篇(下)Day1-2

学习网址:https://datawhalechina.github.io/leetcode-notes/#/ch03/index.md


'''
你一个整数数组 nums 。如果任一值在数组中出现 至少两次 ,返回 true ;如果数组中每个元素互不相同,返回 false 。
 

示例 1:

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

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

输入:nums = [1,1,1,3,3,4,3,2,4,2]
输出:true
 
'''

class Solution(object):
    def containsDuplicate(self, nums):
        """
        :type nums: List[int]
        :rtype: bool
        """
        # 将数组转换为集合
        num_set = set(nums)
        # 比较集合的大小和原数组的大小
        return len(num_set) < len(nums)



'''
给你一个整数数组 nums 和一个整数 k ,判断数组中是否存在两个 不同的索引 i 和 j ,满足 nums[i] == nums[j] 且 abs(i - j) <= k 。如果存在,返回 true ;否则,返回 false 。

 

示例 1:

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

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

输入:nums = [1,2,3,1,2,3], k = 2
输出:false
'''

class Solution(object):
    def containsNearbyDuplicate(self, nums, k):
        """
        :type nums: List[int]
        :type k: int
        :rtype: bool
        """
        # 创建一个空的哈希表(字典),用于存储元素和它们的索引
        num_indices = {}
        
        # 遍历数组中的每个元素
        for i, num in enumerate(nums):
            # 检查元素是否已经在哈希表中
            if num in num_indices and i - num_indices[num] <= k:
                # 如果找到重复的元素,并且索引差小于等于k,返回True
                return True
            # 如果元素不在哈希表中,或者索引差大于k,更新哈希表中的索引
            num_indices[num] = i
        
        # 如果遍历完整个数组都没有找到满足条件的元素对,返回False
        return False



'''
请你判断一个 9 x 9 的数独是否有效。只需要 根据以下规则 ,验证已经填入的数字是否有效即可。

数字 1-9 在每一行只能出现一次。
数字 1-9 在每一列只能出现一次。
数字 1-9 在每一个以粗实线分隔的 3x3 宫内只能出现一次。(请参考示例图)
 

注意:

一个有效的数独(部分已被填充)不一定是可解的。
只需要根据以上规则,验证已经填入的数字是否有效即可。
空白格用 '.' 表示。
 
'''

class Solution(object):
    def isValidSudoku(self, board):
        """
        :type board: List[List[str]]
        :rtype: bool
        """
        # 创建一个集合,用于存储每一行中出现的数字
        rows = [set() for _ in range(9)]
        # 创建一个集合,用于存储每一列中出现的数字
        cols = [set() for _ in range(9)]
        # 创建一个集合,用于存储每一个3x3九宫格中出现的数字
        boxes = [[set() for _ in range(3)] for _ in range(3)]
        
        # 遍历数独的每一个元素
        for i in range(9):
            for j in range(9):
                num = board[i][j]
                # 如果当前位置是空白格,则跳过
                if num == '.':
                    continue
                # 将数字转换为整数类型以便进行比较和存储
                num = int(num)
                
                # 计算当前数字所在的3x3九宫格的索引
                box_i = i // 3
                box_j = j // 3
                
                # 检查行中是否有重复的数字
                if num in rows[i]:
                    return False
                rows[i].add(num)
                
                # 检查列中是否有重复的数字
                if num in cols[j]:
                    return False
                cols[j].add(num)
                
                # 检查3x3九宫格中是否有重复的数字
                if num in boxes[box_i][box_j]:
                    return False
                boxes[box_i][box_j].add(num)
        
        # 如果没有发现重复的数字,则数独有效
        return True
'''
给定两个数组 nums1 和 nums2 ,返回 它们的 
交集
 。输出结果中的每个元素一定是 唯一 的。我们可以 不考虑输出结果的顺序 。

 

示例 1:

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

输入:nums1 = [4,9,5], nums2 = [9,4,9,8,4]
输出:[9,4]
解释:[4,9] 也是可通过的
 

提示:

1 <= nums1.length, nums2.length <= 1000
0 <= nums1[i], nums2[i] <= 1000
'''
class Solution(object):
    def intersection(self, nums1, nums2):
        """
        :type nums1: List[int]
        :type nums2: List[int]
        :rtype: List[int]
        """
        # 将数组nums1里的每一个数值映射到一个哈希表上
        num_set = set(nums1)
        
        # 初始化一个空集合,用于存储交集结果
        intersection_set = set()
        
        # 查询数值nums2里的数值是否在哈希表上,如果有则将该数值添加到交集集合中
        for num in nums2:
            if num in num_set:
                intersection_set.add(num)
        
        # 输出set转换为列表
        return list(intersection_set)
'''给你两个整数数组 nums1 和 nums2 ,请你以数组形式返回两数组的交集。返回结果中每个元素出现的次数,应与元素在两个数组中都出现的次数一致(如果出现次数不一致,则考虑取较小值)。可以不考虑输出结果的顺序。

 

示例 1:

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

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

提示:

1 <= nums1.length, nums2.length <= 1000
0 <= nums1[i], nums2[i] <= 1000
'''
class Solution(object):
    def intersect(self, nums1, nums2):
        """
        :type nums1: List[int]
        :type nums2: List[int]
        :rtype: List[int]
        """
        # 对nums1和nums2进行排序
        nums1.sort()
        nums2.sort()
        
        # 新的空列表用于存储交集
        intersection = []
        
        # 初始化两个列表的索引
        i, j = 0, 0
        
        # 使用双指针方法遍历两个列表
        while i < len(nums1) and j < len(nums2):
            if nums1[i] == nums2[j]:
                # 如果找到相等的元素,则添加到交集列表中,并移动两个指针
                intersection.append(nums1[i])
                i += 1
                j += 1
            elif nums1[i] < nums2[j]:
                # 如果nums1当前元素小于nums2当前元素,移动nums1的指针
                i += 1
            else:
                # 如果nums1当前元素大于nums2当前元素,移动nums2的指针
                j += 1
        
        # 返回交集列表
        return intersection
'''
不使用任何内建的哈希表库设计一个哈希映射(HashMap)。

实现 MyHashMap 类:

MyHashMap() 用空映射初始化对象
void put(int key, int value) 向 HashMap 插入一个键值对 (key, value) 。如果 key 已经存在于映射中,则更新其对应的值 value 。
int get(int key) 返回特定的 key 所映射的 value ;如果映射中不包含 key 的映射,返回 -1 。
void remove(key) 如果映射中存在 key 的映射,则移除 key 和它所对应的 value 。
 

示例:

输入:
["MyHashMap", "put", "put", "get", "get", "put", "get", "remove", "get"]
[[], [1, 1], [2, 2], [1], [3], [2, 1], [2], [2], [2]]
输出:
[null, null, null, 1, -1, null, 1, null, -1]

解释:
MyHashMap myHashMap = new MyHashMap();
myHashMap.put(1, 1); // myHashMap 现在为 [[1,1]]
myHashMap.put(2, 2); // myHashMap 现在为 [[1,1], [2,2]]
myHashMap.get(1);    // 返回 1 ,myHashMap 现在为 [[1,1], [2,2]]
myHashMap.get(3);    // 返回 -1(未找到),myHashMap 现在为 [[1,1], [2,2]]
myHashMap.put(2, 1); // myHashMap 现在为 [[1,1], [2,1]](更新已有的值)
myHashMap.get(2);    // 返回 1 ,myHashMap 现在为 [[1,1], [2,1]]
myHashMap.remove(2); // 删除键为 2 的数据,myHashMap 现在为 [[1,1]]
myHashMap.get(2);    // 返回 -1(未找到),myHashMap 现在为 [[1,1]]
 

提示:

0 <= key, value <= 106
最多调用 104 次 put、get 和 remove 方法
'''
class MyHashMap:
    # 初始化哈希映射类
    def __init__(self):
        self.buckets = 1009  # 设置桶的数量为质数以减少哈希冲突
        self.table = [[] for _ in range(self.buckets)]  # 创建一个列表的列表作为哈希表,每个桶是一个空列表

    # 哈希函数,将键转换为桶的索引
    def hash(self, key):
        return key % self.buckets  # 使用取模运算符计算键的哈希值
    
    # 插入键值对到哈希映射中
    def put(self, key, value):
        hashkey = self.hash(key)  # 计算键的哈希值
        for item in self.table[hashkey]:  # 在对应的桶中查找是否存在相同的键
            if item[0] == key:  # 如果找到相同的键,更新其值
                item[1] = value
                return
        self.table[hashkey].append([key, value])  # 如果没有找到相同的键,将键值对添加到桶中

    # 从哈希映射中获取指定键的值
    def get(self, key):
        hashkey = self.hash(key)  # 计算键的哈希值
        for item in self.table[hashkey]:  # 在对应的桶中查找指定的键
            if item[0] == key:  # 如果找到指定的键,返回其值
                return item[1]
        return -1  # 如果没有找到指定的键,返回-1表示不存在

    # 从哈希映射中移除指定的键及其对应的值
    def remove(self, key):
        hashkey = self.hash(key)  # 计算键的哈希值
        for i, item in enumerate(self.table[hashkey]):  # 在对应的桶中查找指定的键
            if item[0] == key:  # 如果找到指定的键,从桶中移除该键值对
                self.table[hashkey].pop(i)
                return

学习了哈希表和哈希函数是什么:

哈希表的两个核心问题是:「哈希函数的构建」 和 「哈希冲突的解决方法」

  • 常用的哈希函数方法有:直接定址法、除留余数法、平方取中法、基数转换法、数字分析法、折叠法、随机数法、乘积法、点积法等。
  • 常用的哈希冲突的解决方法有两种:开放地址法和链地址法。
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值