【力扣 - 找到字符串中所有字母异位词】

题目描述

给定两个字符串 sp,找到 s 中所有 p 的 异位词 的子串,返回这些子串的起始索引。不考虑答案输出的顺序。

异位词 指由相同字母重排列形成的字符串(包括相同的字符串)。

示例 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" 的异位词。

提示:

1 <= s.length, p.length <= 3 * 10^4
sp 仅包含小写字母

题解 - 滑动窗口

思路

根据题目要求,我们需要在字符串 s 寻找字符串 p 的异位词。因为字符串 p 的异位词的长度一定与字符串 p 的长度相同,所以我们可以在字符串 s 中构造一个长度为与字符串 p 的长度相同的滑动窗口,并在滑动中维护窗口中每种字母的数量;当窗口中每种字母的数量与字符串 p 中每种字母的数量相同时,则说明当前窗口为字符串 p 的异位词。

算法

在算法的实现中,我们可以使用数组来存储字符串 p 和滑动窗口中每种字母的数量。

细节

当字符串 s 的长度小于字符串 p 的长度时,字符串 s 中一定不存在字符串 p 的异位词。但是因为字符串 s 中无法构造长度与字符串 p 的长度相同的窗口,所以这种情况需要单独处理。
在这里插入图片描述

代码

/**
 * Function to check if a string is a match with a given character array
 * @param s: input string
 * @param len: length of the input string
 * @param vat: character array to match against
 * @return true if the string is a match, false otherwise
 */
bool stringIsMatch(char *s, int len, char *vat) {
   
   
    int i;
    char vatBak[26] = {
   
   0};<
LeetCode 上,第 100 题是“相同的树”(Same Tree),而“字母异位词分组”是 LeetCode 第 49 题[^1]。因此,可能存在对题号的混淆。下面将分别讨论这两道题的相关解法背景。 ### 1. LeetCode 第 49 题:字母异位词分组(Group Anagrams) **题目描述** 给定一个字符串数组,将所有字母异位词(anagram)组合在一起。字母异位词是指由相同字母不同顺序构成的字符串。 **解法思路** 解决该问题的核心思想是:**字母异位词在排序后具有相同的字符串形式**。因此,可以利用哈希表(Map)来将相同排序后的字符串作为键,对应的原始字符串列表作为值。 #### Java 解法示例(排序 + 哈希表) ```java class Solution { public List<List<String>> groupAnagrams(String[] strs) { Map<String, List<String>> map = new HashMap<>(); for (String str : strs) { char[] arr = str.toCharArray(); Arrays.sort(arr); String key = new String(arr); List<String> list = map.getOrDefault(key, new ArrayList<>()); list.add(str); map.put(key, list); } return new ArrayList<>(map.values()); } } ``` #### Java 解法示例(计数 + 哈希表) 该方法适用于字符集较大的情况,例如 Unicode 字符。它基于字符出现的频率构建键值。 ```java public List<List<String>> groupAnagrams(String[] strs) { Map<String, List<String>> map = new HashMap<>(); for (String str : strs) { int[] count = new int[26]; for (char c : str.toCharArray()) { count[c - 'a']++; } StringBuilder key = new StringBuilder(); for (int i = 0; i < 26; i++) { key.append(count[i]).append('#'); } String keyStr = key.toString(); if (!map.containsKey(keyStr)) { map.put(keyStr, new ArrayList<>()); } map.get(keyStr).add(str); } return new ArrayList<>(map.values()); } ``` **时间复杂度分析** - 排序法:O(n * k log k),其中 `n` 是字符串数量,`k` 是字符串的最大长度。 - 计数法:O(n * k),其中 `k` 是字符串的平均长度,适用于较长字符串的情况。 **空间复杂度** - O(n * k),用于存储哈希表中的键值对。 ### 2. LeetCode 第 100 题:相同的树(Same Tree) **题目描述** 给定两棵二叉树,判断它们是否相同。两棵树相同当且仅当它们的结构相同,并且每个节点的值也相同。 **解法思路** 可以通过递归或迭代的方式比较两棵树的每个节点: - 如果当前节点都为空,则相同。 - 如果一个为空而另一个非空,则不相同。 - 如果节点值不同,则不相同。 - 否则递归比较左右子树。 #### Java 解法示例(递归) ```java public boolean isSameTree(TreeNode p, TreeNode q) { if (p == null && q == null) return true; if (p == null || q == null) return false; return p.val == q.val && isSameTree(p.left, q.left) && isSameTree(p.right, q.right); } ``` #### Java 解法示例(迭代,使用队列) ```java public boolean isSameTree(TreeNode p, TreeNode q) { Queue<TreeNode> queue = new LinkedList<>(); queue.offer(p); queue.offer(q); while (!queue.isEmpty()) { TreeNode node1 = queue.poll(); TreeNode node2 = queue.poll(); if (node1 == null && node2 == null) continue; if (node1 == null || node2 == null || node1.val != node2.val) return false; queue.offer(node1.left); queue.offer(node2.left); queue.offer(node1.right); queue.offer(node2.right); } return true; } ``` **时间复杂度** - O(n),其中 `n` 是树的节点数。 **空间复杂度** - 最坏情况下为 O(n),取决于树的高度。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

六月悉茗

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

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

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

打赏作者

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

抵扣说明:

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

余额充值