刷穿剑指offer-Day15-哈希表II Python&Java的哈希表方法与解题套路!

简介: 刷穿剑指offer-Day15-哈希表II Python&Java的哈希表方法与解题套路!

昨日回顾


昨天我们开始了哈希表的学习,讲解了哈希表的集中实现方式。并通过一道 设计哈希集合 的题目,让我们将哈希表的理论转化为实践。

今天,我们就开始正式学习哈希表在Python与Java中的使用方式。在Java中,哈希表有两个数据类型 HashMap 与 HashSet,它们对应Python中的 dict 与 set ,下面我们开始分类学习!


HashSet & set


我们在昨天的设计哈希集合题目中,对HashSet已经有了一个初步的了解。HashSet与set 是一个无序不重复的元素集,集合在我们日常算法中对数组去重、已搜索的节点记录等有很大帮助。

具体方法如下:

操作 Python Java
初始化 s = set() HashSet<Integer> s = new HashSet<>();
增加 s.add(1) s.add(1)
删除 s.remove(1) 不存在报错
s.discard(2) 不存在不报错
s.pop()随机弹出并返回
s.remove(1) 不存在不报错
包含 1 in s s.contains(1)
获取长度 len(s) s.size()
清空 s.clear() s.clear()
查看是否为空 if not s s.isEmpty()

Python针对集合还可存在update更新、difference 并可以使用 | & 等方法,但在算法中的使用频度并不高,大家下来可以自行复习。


HashMap & dict


就如力扣 twoSum 这道题中,题目要求我们在数组中查找等于 target 的两个元素,并返回这两个数字的下标。如果只是判断能否找到这两个数,我们初始化一个HashSet,在遍历数组的过程中检查target - num 是否在存在HashSet中,如果找到直接返回True,否则将当前数字保存至HashSet中。

但既然要返回下标,就需要在保存数字的同时记录该数字的下标。使用方式如下图:


网络异常,图片无法展示
|

让我们来看看Python和Java中HashMap 和dict 都有哪些方法吧:

操作 Python Java
初始化 d = {} d = dict() HashMap<Integer,Integer> d = new HashMap<>();
增加键值对、已存在则修改 d[2] = 0 d.put(2,0);
获取key对应value d[2] d.get(2)
获取key,不存在则返回默认 d.get(3, -1) d.getOrDefault(3, -1)
删除某个键 del d[5] 不存在报错
d.pop(5, -1) 不存在返回默认值机
d.popitem() 随机删除一个键值对
d.remove(5) 不存在不报错
当key不存在时添加 d.setdefault(9, 0) d.putIfAbsent(9, 0)
获取长度 len(s) s.size()
包含 1 in s s.contains(1)
清空 s.clear() s.clear()
查看是否为空 if not s s.isEmpty()

剩余一些通用的d.keys() d.values() d.items()获取字典所有键、值、键值对等就不再赘述了,大家下来可以自行复习。

关于HashSet、set和HashMap、dict的相关知识就复习到这里。下来让我们做第一题熟悉熟悉?嗯...还是换个稍微有点难度的吧。


剑指OfferII032.有效的变位词


https://leetcode-cn.com/problems/dKk3P7/solution/shua-chuan-jian-zhi-offer-day15-ha-xi-bi-5pqx/

难度:简单


题目

给定两个字符串 s 和 t ,编写一个函数来判断它们是不是一组变位词(字母异位词)。

注意:若 s 和 t 中每个字符出现的次数都相同且字符顺序不完全相同,则称 s 和 t 互为变位词(字母异位词)。

进阶: 如果输入字符串包含 unicode 字符怎么办?你能否调整你的解法来应对这种情况?

提示:

  • 1 <= s.length, t.length <= 5 * 10 ^ 4
  • s and t 仅包含小写字母


示例

示例 1:
输入: s = "anagram", t = "nagaram"
输出: true
示例 2:
输入: s = "rat", t = "car"
输出: false
示例 3:
输入: s = "a", t = "a"
输出: false


分析

在不看进阶的情况下,这道题其实用不到哈希表,因为s和t只包含小写字母,我们在字符串和数组那章节已经讲过了这种题目的快速解法。

我们通过构造一个长度为26的数组对应26个英文字母(嗯...突然想起,谭警官的28个英文字母倒背如流,怕了怕了...)

通过字符串与ascii对应的方式完成匹配,这套路用的太多就不细讲了。

但是,进阶中说了,如果字符串包含unicode字符串怎么办?

怎么办,凉拌....直接上哈希表就行了啊!

其他操作和数据没什么区别,只是换成了哈希表的对应方法而已么。


数组解题


Python:

class Solution:
    def isAnagram(self, s: str, t: str) -> bool:
        if len(s) != len(t) or s == t:
            return False
        comp = [0] * 26
        for i in s:
            comp[ord(i) - 97] += 1
        for j in t:
            index = ord(j) - 97
            if comp[index] < 1:
                return False
            comp[index] -= 1
        return True


Python:

class Solution {
    public boolean isAnagram(String s, String t) {
        if (s.length() != t.length() || s.equals(t)) {
            return false;
        }
        int[] arr = new int[26];
        for (char i:s.toCharArray()) {
            arr[i - 97]++;
        }
        for (char j:t.toCharArray()) {
            arr[j - 97]--;
            if (arr[j - 97] < 0){
                return false;
            }
        }
        return true;
    }
}


哈希表解题


Python:

class Solution:
    def isAnagram(self, s: str, t: str) -> bool:
        return s != t and Counter(s) == Counter(t)


Python:

class Solution {
    public boolean isAnagram(String s, String t) {
        if (s.length() != t.length() || s.equals(t)) {
            return false;
        }
        HashMap<Character, Integer> arr = new HashMap<>();
        for (char i : s.toCharArray()) {
            arr.put(i, arr.getOrDefault(i, 0) + 1);
        }
        for (char j : t.toCharArray()) {
            if (!arr.containsKey(j) || arr.get(j) == 0)
                return false;
            arr.put(j, arr.get(j) - 1);
        }
        return true;
    }
}

不得不说Python做这种类型的题目简直是无脑啊....请恕我偷懒了,哈哈。

经过这道简单题的铺垫,再来看下面这道中等题,可以说就那会儿事儿....手速题而已!


剑指OfferII033.变位词组


https://leetcode-cn.com/problems/sfvd7V/solution/shua-chuan-jian-zhi-offer-day15-ha-xi-bi-p57n/

难度:中等


题目

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

注意:若两个字符串中每个字符出现的次数都相同,则称它们互为变位词。

提示:

  • 1 <= strs.length <= 104
  • 0 <= strs[i].length <= 100
  • strs[i] 仅包含小写字母


示例

示例 1:
输入: strs = ["eat", "tea", "tan", "ate", "nat", "bat"]
输出: [["bat"],["nat","tan"],["ate","eat","tea"]]
示例 2:
输入: strs = [""]
输出: [[""]]
示例 3:
输入: strs = ["a"]
输出: [["a"]]


分析

这道题在难度方面并不高,思路其实剑指OfferII032类似的:

  1. 我们创建一个哈希表s,key 为String,value 为List
  2. 然后循环列表中的每个字符串,先将字符串排序
  3. 再看排序后的字符串是否在哈希表中,如果在则追加,如果不在单独开辟一对key:value即可
  4. 最终将哈希表的value值转化为列表返回即可。

但对于 Python 这里还有一个优化点的,如果按照上面的方式,我们需要创建一个哈希表嵌套列表的操作。

而且最终有需要将哈希表的value转化为列表再返回比较麻烦。

我们可以换个思路:

  1. 我们单独创建一个哈希表s和列表li
  2. 当哈希表中不存在排序后的字符串时,我们获取当前列表长度作为value(其实是列表的下标)
  3. 然后向哈希表中插入 key = 排序后的字符串, value = 该字符串在列表中的下标。
  4. 下次遇到同类型的字符串,我们直接在列表对应下标中插入该字符串即可。


解题


Python:

class Solution:
    def groupAnagrams(self, strs):
        ret = []
        d = {}
        for i in strs:
            sort_i = ''.join(sorted(i))
            if sort_i in d:
                ret[d[sort_i]].append(i)
            else:
                d[sort_i] = len(ret)
                ret.append([i])
        return ret


Java:

class Solution {
    public List<List<String>> groupAnagrams(String[] strs) {
        HashMap<String, ArrayList<String>> map = new HashMap<String, ArrayList<String>>();
        for (String str : strs) {
            char[] array = str.toCharArray();
            Arrays.sort(array);
            String key = new String(array);
            ArrayList<String> list = map.getOrDefault(key, new ArrayList<String>());
            list.add(str);
            map.put(key, list);
        }
        return new ArrayList<List<String>>(map.values());
    }
}

好了,今天的哈希表学习就到这里,题目虽然基础,但是一定要练习啊!




目录
打赏
0
0
0
0
1
分享
相关文章
通义灵码 Rules 库合集来了,覆盖Java、TypeScript、Python、Go、JavaScript 等
通义灵码新上的外挂 Project Rules 获得了开发者的一致好评:最小成本适配我的开发风格、相当把团队经验沉淀下来,是个很好功能……
318 75
|
1月前
|
时间序列异常检测:MSET-SPRT组合方法的原理和Python代码实现
MSET-SPRT是一种结合多元状态估计技术(MSET)与序贯概率比检验(SPRT)的混合框架,专为高维度、强关联数据流的异常检测设计。MSET通过历史数据建模估计系统预期状态,SPRT基于统计推断判定偏差显著性,二者协同实现精准高效的异常识别。本文以Python为例,展示其在模拟数据中的应用,证明其在工业监控、设备健康管理及网络安全等领域的可靠性与有效性。
573 13
时间序列异常检测:MSET-SPRT组合方法的原理和Python代码实现
Python数值方法在工程和科学问题解决中的应用
本文探讨了Python数值方法在工程和科学领域的广泛应用。首先介绍了数值计算的基本概念及Python的优势,如易学易用、丰富的库支持和跨平台性。接着分析了Python在有限元分析、信号处理、优化问题求解和控制系统设计等工程问题中的应用,以及在数据分析、机器学习、模拟建模和深度学习等科学问题中的实践。通过具体案例,展示了Python解决实际问题的能力,最后总结展望了Python在未来工程和科学研究中的发展潜力。
|
17天前
|
Java 中的 toString() 方法详解:为什么它如此重要?
在Java开发中,`toString()`方法至关重要,用于返回对象的字符串表示。默认实现仅输出类名和哈希码,信息有限且不直观。通过重写`toString()`,可展示对象字段值,提升调试效率与代码可读性。借助Lombok的`@Data`注解,能自动生成标准化的`toString()`方法,简化开发流程,尤其适合字段较多的场景。合理运用`toString()`,可显著提高开发效率与代码质量。
50 0
|
10天前
|
解决Python报错:DataFrame对象没有concat属性的多种方法(解决方案汇总)
总的来说,解决“DataFrame对象没有concat属性”的错误的关键是理解concat函数应该如何正确使用,以及Pandas库提供了哪些其他的数据连接方法。希望这些方法能帮助你解决问题。记住,编程就像是解谜游戏,每一个错误都是一个谜题,解决它们需要耐心和细心。
54 15
|
17天前
|
[oeasy]python086方法_method_函数_function_区别
本文详细解析了Python中方法(method)与函数(function)的区别。通过回顾列表操作如`append`,以及随机模块的使用,介绍了方法作为类的成员需要通过实例调用的特点。对比内建函数如`print`和`input`,它们无需对象即可直接调用。总结指出方法需基于对象调用且包含`self`参数,而函数独立存在无需`self`。最后提供了学习资源链接,方便进一步探索。
53 17
uv安装python及其依赖的加速方法
国内在使用uv的时候,可能会涉及到装python的速度太慢的问题,为了解决这个问题,可以使用`UV_PYTHON_INSTALL_MIRROR`这个环境变量。除此以外,对于多人协作场景,`UV_CACHE_DIR`也是一个有用的环境变量。本文会介绍这两个变量。
335 10
Java 中的 equals 方法:看似简单,实则深藏玄机
本文深入探讨了Java中`equals`方法的设计与实现。默认情况下,`equals`仅比较对象引用是否相同。以`String`类为例,其重写了`equals`方法,通过引用判断、类型检查、长度对比及字符逐一比对,确保内容相等的逻辑。文章还强调了`equals`方法需遵循的五大原则(自反性、对称性等),以及与`hashCode`的关系,避免集合操作中的潜在问题。最后,对比了`instanceof`和`getClass()`在类型判断中的优劣,并总结了正确重写`equals`方法的重要性,帮助开发者提升代码质量。
51 1
从命名约定到特殊方法,Python下划线符号的妙用!
下划线(`_`)是Python开发者日常接触的重要符号,其含义和应用场景多样。本文全面解析了Python中下划线的不同用法,包括单下划线作为临时变量、国际化翻译函数、交互式解释器特殊变量;单下划线前缀表示保护成员;单下划线后缀避免关键字冲突;双下划线前缀触发名称改写;双下划线前后缀定义特殊方法等。此外,还介绍了数字分隔符、模式匹配通配符等新特性,并总结了下划线使用的最佳实践与常见问题解答。通过本文,读者可深入了解下划线在Python中的多重角色及其设计哲学。
58 2
|
1月前
|
《从头开始学java,一天一个知识点》之:方法定义与参数传递机制
**你是否也经历过这些崩溃瞬间?** - 看了三天教程,连`i++`和`++i`的区别都说不清 - 面试时被追问&quot;`a==b`和`equals()`的区别&quot;,大脑突然空白 - 写出的代码总是莫名报NPE,却不知道问题出在哪个运算符 🚀 这个系列就是为你打造的Java「速效救心丸」!我们承诺:每天1分钟,地铁通勤、午休间隙即可完成学习;直击痛点,只讲高频考点和实际开发中的「坑位」;拒绝臃肿,没有冗长概念堆砌,每篇都有可运行的代码标本。上篇:《输入与输出:Scanner与System类》 | 下篇剧透:《方法重载与可变参数》。
56 25
AI助理

你好,我是AI助理

可以解答问题、推荐解决方案等