LeetCode 1624. 两个相同字符之间的最长子字符串【字符串,哈希映射】1281

本文主要是介绍LeetCode 1624. 两个相同字符之间的最长子字符串【字符串,哈希映射】1281,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

本文属于「征服LeetCode」系列文章之一,这一系列正式开始于2021/08/12。由于LeetCode上部分题目有锁,本系列将至少持续到刷完所有无锁题之日为止;由于LeetCode还在不断地创建新题,本系列的终止日期可能是永远。在这一系列刷题文章中,我不仅会讲解多种解题思路及其优化,还会用多种编程语言实现题解,涉及到通用解法时更将归纳总结出相应的算法模板。

为了方便在PC上运行调试、分享代码文件,我还建立了相关的仓库:https://github.com/memcpy0/LeetCode-Conquest。在这一仓库中,你不仅可以看到LeetCode原题链接、题解代码、题解文章链接、同类题目归纳、通用解法总结等,还可以看到原题出现频率和相关企业等重要信息。如果有其他优选题解,还可以一同分享给他人。

由于本系列文章的内容随时可能发生更新变动,欢迎关注和收藏征服LeetCode系列文章目录一文以作备忘。

给你一个字符串 s,请你返回 两个相同字符之间的最长子字符串的长度 ,计算长度时不含这两个字符。如果不存在这样的子字符串,返回 -1 。

子字符串 是字符串中的一个连续字符序列。

示例 1:

输入:s = "aa"
输出:0
解释:最优的子字符串是两个 'a' 之间的空子字符串。

示例 2:

输入:s = "abca"
输出:2
解释:最优的子字符串是 "bc"

示例 3:

输入:s = "cbzxy"
输出:-1
解释:s 中不存在出现出现两次的字符,所以返回 -1

示例 4:

输入:s = "cabbac"
输出:4
解释:最优的子字符串是 "abba" ,其他的非最优解包括 "bb"""

提示:

  • 1 <= s.length <= 300
  • s 只含小写英文字母

解法 哈希表

求出两个相同字符之间的最长子字符串的长度:对于字符 c h ch ch,只需要求出 c h ch ch 第一次出现在字符串中的索引位置 f i r s t first first 和最后一次出现在字符串中的索引位置 l a s t last last ,则以 c h ch ch 为相同字符之间的子字符串的最大长度一定为 l a s t − f i r s t − 1 last−first−1 lastfirst1 ,依次求出所有可能的子字符串的长度的最大值即可。我们设数组 firstIndex \textit{firstIndex} firstIndex 记录每个字符 i i i 在字符串中第一次出现的索引, m a x L e n g t h maxLength maxLength 表示当前子字符串的最大长度。

初始化时 f i r s t I n d e x firstIndex firstIndex 中的每个元素都初始化为 − 1 -1 1 ,表示该字符还未出现。

  • 当遍历到第 i i i 个字符 c h ch ch 时,如果当前数组中 f i r s t I n d e x [ c h ] = − 1 firstIndex[ch]=−1 firstIndex[ch]=1 ,则记录该字符第一次出现的索引为 i i i ,更新 firstIndex [ ch ] = i \textit{firstIndex}[\textit{ch}] = i firstIndex[ch]=i
  • 如果当前数组中 f i r s t I n d e x [ c h ] ≥ 0 firstIndex[ch]≥0 firstIndex[ch]0 时,则表示字符 c h ch ch 之前已经出现过,此时两个 c h ch ch 之间的子字符串长度为 i − f i r s t I n d e x [ c h ] − 1 i−firstIndex[ch]−1 ifirstIndex[ch]1 ,同时更新 m a x L e n g t h maxLength maxLength

返回最大的长度 m a x L e n g t h maxLength maxLength 即可。

// cpp
class Solution {
public:int maxLengthBetweenEqualCharacters(string s) {int maxLength = -1;vector<int> firstIndex(26, -1);for (int i = 0; i < s.size(); ++i) {if (firstIndex[s[i] - 'a'] < 0) {firstIndex[s[i] - 'a'] = i;} else {maxLength = max(maxLength, i - firstIndex[s[i] - 'a'] - 1);}}return maxLength;}
};// java
class Solution {public int maxLengthBetweenEqualCharacters(String s) {int maxLength = -1;int[] firstIndex = new int[26];Arrays.fill(firstIndex, -1);for (int i = 0; i < s.length(); ++i) {if (firstIndex[s.charAt(i) - 'a'] < 0) {firstIndex[s.charAt(i) - 'a'] = i;} else {maxLength = Math.max(maxLength, i - firstIndex[s.charAt(i) - 'a'] - 1);}}return maxLength;}
}// python
class Solution:def maxLengthBetweenEqualCharacters(self, s: str) -> int:ans = -1firstIndex = {}for i, c in enumerate(s):if c not in firstIndex:firstIndex[c] = ielse:ans = max(ans, i - firstIndex[c] - 1)return ans// go
func maxLengthBetweenEqualCharacters(s string) int {ans := -1firstIndex := [26]int {}for i := range firstIndex {firstIndex[i] = -1}for i, c := range s {c -= 'a'if firstIndex[c] < 0 {firstIndex[c] = i} else {ans = max(ans, i - firstIndex[c] - 1)}}return ans
}func max(a, b int) int {if b > a {return b}return a
}

复杂度分析:

  • 时间复杂度: O ( n ) O(n) O(n) ,其中 n n n 表示字符串的长度。我们只需遍历一遍字符串即可。
  • 空间复杂度: O ( ∣ Σ ∣ ) O(|\Sigma|) O(∣Σ∣) ,其中 Σ \Sigma Σ 是字符集,在本题中字符集为所有小写字母, ∣ Σ ∣ = 26 |\Sigma|=26 ∣Σ∣=26

这篇关于LeetCode 1624. 两个相同字符之间的最长子字符串【字符串,哈希映射】1281的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/558526

相关文章

哈希leetcode-1

目录 1前言 2.例题  2.1两数之和 2.2判断是否互为字符重排 2.3存在重复元素1 2.4存在重复元素2 2.5字母异位词分组 1前言 哈希表主要是适合于快速查找某个元素(O(1)) 当我们要频繁的查找某个元素,第一哈希表O(1),第二,二分O(log n) 一般可以分为语言自带的容器哈希和用数组模拟的简易哈希。 最简单的比如数组模拟字符存储,只要开26个c

spoj705( 求不相同的子串个数)

题意:求串s的不同子串的个数 解题思路:任何子串都是某个后缀的前缀,对n个后缀排序,求某个后缀的前缀的个数,减去height[i](第i个后缀与第i-1 个后缀有相同的height[i]个前缀)。 代码如下: #include<iostream>#include<algorithm>#include<stdio.h>#include<math.h>#include<cstrin

usaco 1.3 Prime Cryptarithm(简单哈希表暴搜剪枝)

思路: 1. 用一个 hash[ ] 数组存放输入的数字,令 hash[ tmp ]=1 。 2. 一个自定义函数 check( ) ,检查各位是否为输入的数字。 3. 暴搜。第一行数从 100到999,第二行数从 10到99。 4. 剪枝。 代码: /*ID: who jayLANG: C++TASK: crypt1*/#include<stdio.h>bool h

day-51 合并零之间的节点

思路 直接遍历链表即可,遇到val=0跳过,val非零则加在一起,最后返回即可 解题过程 返回链表可以有头结点,方便插入,返回head.next Code /*** Definition for singly-linked list.* public class ListNode {* int val;* ListNode next;* ListNode() {}*

uva 10131 最长子序列

题意: 给大象的体重和智商,求体重按从大到小,智商从高到低的最长子序列,并输出路径。 代码: #include <iostream>#include <cstdio>#include <cstdlib>#include <algorithm>#include <cstring>#include <cmath>#include <stack>#include <vect

leetcode-24Swap Nodes in Pairs

带头结点。 /*** Definition for singly-linked list.* public class ListNode {* int val;* ListNode next;* ListNode(int x) { val = x; }* }*/public class Solution {public ListNode swapPairs(L

leetcode-23Merge k Sorted Lists

带头结点。 /*** Definition for singly-linked list.* public class ListNode {* int val;* ListNode next;* ListNode(int x) { val = x; }* }*/public class Solution {public ListNode mergeKLists

C++ | Leetcode C++题解之第393题UTF-8编码验证

题目: 题解: class Solution {public:static const int MASK1 = 1 << 7;static const int MASK2 = (1 << 7) + (1 << 6);bool isValid(int num) {return (num & MASK2) == MASK1;}int getBytes(int num) {if ((num &

两个月冲刺软考——访问位与修改位的题型(淘汰哪一页);内聚的类型;关于码制的知识点;地址映射的相关内容

1.访问位与修改位的题型(淘汰哪一页) 访问位:为1时表示在内存期间被访问过,为0时表示未被访问;修改位:为1时表示该页面自从被装入内存后被修改过,为0时表示未修改过。 置换页面时,最先置换访问位和修改位为00的,其次是01(没被访问但被修改过)的,之后是10(被访问了但没被修改过),最后是11。 2.内聚的类型 功能内聚:完成一个单一功能,各个部分协同工作,缺一不可。 顺序内聚:

【每日一题】LeetCode 2181.合并零之间的节点(链表、模拟)

【每日一题】LeetCode 2181.合并零之间的节点(链表、模拟) 题目描述 给定一个链表,链表中的每个节点代表一个整数。链表中的整数由 0 分隔开,表示不同的区间。链表的开始和结束节点的值都为 0。任务是将每两个相邻的 0 之间的所有节点合并成一个节点,新节点的值为原区间内所有节点值的和。合并后,需要移除所有的 0,并返回修改后的链表头节点。 思路分析 初始化:创建一个虚拟头节点