力扣刷题——哈希表

第1题 两数之和

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

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

你可以按任意顺序返回答案。

示例 1:

输入:nums = [2,7,11,15], target = 9
输出:[0,1]
解释:因为 nums[0] + nums[1] == 9 ,返回 [0, 1] 。
示例 2:

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

输入:nums = [3,3], target = 6
输出:[0,1]

我的思路

双层for循环,依次遍历数组相加。
外层循环从0开始,到k-1停止,计算到倒数第二个元素。
内层循环从i+1开始,防止相同元素重复相加、防止输出重复结果;到k+1停止,计算到最后一个元素。

== 易错点:return result应该放在外层循环结束后。因为假设只有一个符合要求的值。==

class Solution(object):
    def twoSum(self, nums, target):
        """
        :type nums: List[int]
        :type target: int
        :rtype: List[int]
        """
        k = len (nums)
        k = k-1
        
        result = []
        
        for i in range(k):
            for j in range(i+1,k+1):
                if nums[i]+nums[j]==target:
                    result.append(i)
                    result.append(j)
        return result
                

最终提交耗时2432ms:
在这里插入图片描述
瞬间感觉自己真的是个小菜鸡,学习一下大神们的解法。

大神解法

class Solution(object):
    def twoSum(self, nums, target):
        """
        :type nums: List[int]
        :type target: int
        :rtype: List[int]
        """
        map={}
        for i in range(len(nums)):
            if map.has_key(target - nums[i]):
                return [i, map.get(target - nums[i])]
            else:
                map[nums[i]] = i

这种方法使用了哈希表,哈希表可以简单理解为电话簿(把一个人的姓名按首字母散列排序)。查找target-sum[i]的结果是否在哈希表里,如果在,那这个索引和i就是题目所求。

总结 哈希表基本使用方法

1、for循环
今天学习了python的for循环的结束点不包括最后一个值。比如for i in range(5) 就是i从0到4,执行了5次循环。

2、哈希表
散列索引 语法如下

#定义一个hash表 名叫color
color = {}

#查看表里有没有某个元素 red
color.has_key(red)

#获取表中某个元素的索引 
color.get(red)

#添加新元素blue到表中索引 i 处
color [blue] = i


第217题 存在重复元素

给你一个整数数组 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
        """
        firstnum=nums[0]
        for i in range(len(nums)):
            firstnum=nums[i]
            for j in range(i+1,len(nums)):
                if nums[j]==firstnum:
                    return True
            
        return False

提交后运行超时了。尝试使用哈希表解决

class Solution(object):
    def containsDuplicate(self, nums):
        """
        :type nums: List[int]
        :rtype: bool
        """
        #新建一个叫map的哈希表
        map = {}
        
        for i in range(len(nums)):
            #如果nums[i]元素已经在哈希表中有索引
            #返回true
            if map.has_key(nums[i]):
                return True
            
            #如果没有索引,则把这个值加入到哈希表中
            else:
                map [nums[i]]=i
        return False

提交之后的结果,执行时长52ms,击败61.12%;消耗内存25.43MB,击败60.97%。

大神解法
看评论区有人使用set()函数去重,然后比较前后长度,遂采纳这种思路。

class Solution(object):
    def containsDuplicate(self, nums):
        """
        :type nums: List[int]
        :rtype: bool
        """
        num2=set(nums)
        if len(num2)!=len(nums):
            return True
        else:
            return False
            

提交之后的结果,执行时长40ms,击败95.41%;消耗内存26.07MB,击败47.2%。

总结 哈希表的索引判断及新增节点

在此题中,哈希表操作主要用到了
1、map.has_key的判断
2、哈希表名 [新加元素] = 索引号的方法添加新元素。

第49题 字母异位词分组

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

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

我的思路

先把单词中的每个字母按顺序排好,然后比较。虽然输出有误,但是可以分析一下我的错误代码。

class Solution(object):
    def groupAnagrams(self, strs):
        """
        :type strs: List[str]
        :rtype: List[List[str]]
        """
        map = {}
        for str in strs:
            word_sort = ''.join(sorted(str))
            map[word_sort]= str

        return list(map.values())

在这里插入图片描述
首先,输出结果有误。其次,输出格式也有误。

因为map[word_sort]= str这一句是将str这个键指向的内容换成word_sort,这样就会替换掉链表中节点的内容,而不是追加一个元素到节点中。所以输出中每个节点也只有一个元素。

所以在新建链表时,应使用map = collections.defaultdict(list) 来新建一个链表。

collections.defaultdict 是 Python 中的一个内建类型,它是一个类似于字典(dict)的容器类型,但是它具有更强的扩展性和易用性。

例如,

import collections

# 创建一个 defaultdict 对象
map = collections.defaultdict(list)

# 向字典中添加元素
map["key1"].append("value1")
map["key2"].append("value2")
map["key1"].append("value3")

print(map)

这一段代码的输出是 [“value1”,“value3”] , [“value2”]

也就是说,key1对应了两个元素,key2对应了一个元素。

采用这种思想,这道题应该有如下解法:

class Solution(object):
    def groupAnagrams(self, strs):
        """
        :type strs: List[str]
        :rtype: List[List[str]]
        """
        map = collections.defaultdict(list) 
        for str in strs:
            word_sort = ''.join(sorted(str))
            map[word_sort].append(str)

        return list(map.values())

输出正确。

总结 哈希表一个节点存储多个数据

1、首先,需要新建一个dict结构的哈希表:

map = collections.defaltdice(这里填写单个节点的类型)

如map = collections.defaltdice(list)
意为创建一个新的defaultdict对象,默认的值的类型为列表。

也就是说,当访问一个不存在的键时,如果这个这个键会自动被添加到字典中,并且将其对应的值初始化为新列表。

2、向节点中追加元素,而不是替换。

语法:
map[键].append(要追加的元素)

示例:
map[word_sort].append(str)

意为将字符串str向map链表中追加到键为word_sort的节点中。

  • 12
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
好的,关于力扣刷题C++常用操作,我可以给你一些常见的操作和技巧: 1. 使用 STL 容器和算法库:STL(Standard Template Library)是 C++ 标准库中的一个重要组成部分,包含了许多常用的容器和算法。在力扣刷题中,使用 STL 可以大大提高代码的效率和可读性。例如,vector 可以用来存储动态数组,sort 可以用来排序等等。 2. 使用 auto 关键字:auto 关键字可以自动推导变量类型,可以减少代码量和提高可读性。例如,auto x = 1; 可以自动推导出 x 的类型为 int。 3. 使用 lambda 表达式:lambda 表达式是 C++11 中引入的一种匿名函数,可以方便地定义一些简单的函数对象。在力扣刷题中,使用 lambda 表达式可以简化代码,例如在 sort 函数中自定义比较函数。 4. 使用位运算:位运算是一种高效的运算方式,在力扣刷题中经常会用到。例如,左移运算符 << 可以用来计算 2 的幂次方,右移运算符 >> 可以用来除以 2 等等。 5. 使用递归:递归是一种常见的算法思想,在力扣刷题中也经常会用到。例如,二叉树的遍历、链表的反转等等。 6. 使用 STL 中的 priority_queue:priority_queue 是 STL 中的一个容器,可以用来实现堆。在力扣刷题中,使用 priority_queue 可以方便地实现一些需要维护最大值或最小值的算法。 7. 使用 STL 中的 unordered_map:unordered_map 是 STL 中的一个容器,可以用来实现哈希表。在力扣刷题中,使用 unordered_map 可以方便地实现一些需要快速查找和插入的算法。 8. 使用 STL 中的 string:string 是 STL 中的一个容器,可以用来存储字符串。在力扣刷题中,使用 string 可以方便地处理字符串相关的问题。 9. 注意边界条件:在力扣刷题中,边界条件往往是解决问题的关键。需要仔细分析题目,考虑各种边界情况,避免出现错误。 10. 注意时间复杂度:在力扣刷题中,时间复杂度往往是评判代码优劣的重要指标。需要仔细分析算法的时间复杂度,并尽可能优化代码。

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

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值