给定一个字符串,打印最长的子字符串,不要重复字符。例如,对于“ABDEFGABEF”,最长的没有重复字符的子串是“BDEFGA”和“DEFGAB”,长度为6。对于“BBBB”,最长的子串是“B”,长度为1。所需的时间复杂度为O(n ) 其中 n 是字符串的长度。
先决条件:无重复字符的最长子串的长度
例子:
Input : GEEKSFORGEEKS
Output : EKSFORG
Input : ABDEFGABEF
Output : BDEFGA
方法:这个想法是遍历字符串,并为每个已经访问过的字符存储在哈希表中的最后一次出现(这里 unordered_map 用作哈希,键作为字符,值作为其最后位置)。变量st存储当前子串的起始点,maxlen存储最大长度子串的长度,start存储最大长度子串的起始索引。在遍历字符串,检查当前字符是否存在于哈希表中。如果不存在,则将当前字符存储在哈希表中,并将 value 作为当前索引。如果它已经存在于哈希表中,这意味着当前字符可以在当前子字符串中重复。对于此检查,上一次出现的字符是在当前子串的起始点 st 之前还是之后。如果在 st 之前,则只更新哈希表中的值。如果在st之后,则求当前子串currlen的长度为i-st,其中i为当前索引。将 currlen 与 maxlen 进行比较。如果 maxlen 小于 currlen,则将 maxlen 更新为 currlen 并从 st 开始。完全遍历字符串,需要的最长不重复字符的子串是从s[start]到s[start+maxlen-1]。
执行:
C++
// C++ program to find and print longest
// substring without repeating characters.
#include
using namespace std;
// Function to find and print longest
// substring without repeating characters.
string findLongestSubstring(string str)
{
int i;
int n = str.length();
// starting point of current substring.
int st = 0;
// length of current substring.
int currlen;
// maximum length substring without repeating
// characters.
int maxlen = 0;
// starting index of maximum length substring.
int start;
// Hash Map to store last occurrence of each
// already visited character.
unordered_map pos;
// Last occurrence of first character is index 0;
pos[str[0]] = 0;
for (i = 1; i < n; i++) {
// If this character is not present in hash,
// then this is first occurrence of this
// character, store this in hash.
if (pos.find(str[i]) == pos.end())
pos[str[i]] = i;
else {
// If this character is present in hash then
// this character has previous occurrence,
// check if that occurrence is before or after
// starting point of current substring.
if (pos[str[i]] >= st) {
// find length of current substring and
// update maxlen and start accordingly.
currlen = i - st;
if (maxlen < currlen) {
maxlen = currlen;
start = st;
}
// Next substring will start after the last
// occurrence of current character to avoid
// its repetition.
st = pos[str[i]] + 1;
}
// Update last occurrence of
// current character.
pos[str[i]] = i;
}
}
// Compare length of last substring with maxlen and
// update maxlen and start accordingly.
if (maxlen < i - st) {
maxlen = i - st;
start = st;
}
// The required longest substring without
// repeating characters is from str[start]
// to str[start+maxlen-1].
return str.substr(start, maxlen);
}
// Driver function
int main()
{
string str = "GEEKSFORGEEKS";
cout << findLongestSubstring(str);
return 0;
}
Java
// Java program to find
// and print longest substring
// without repeating characters.
import java.util.*;
class GFG{
// Function to find and print longest
// substring without repeating characters.
public static String findLongestSubstring(String str)
{
int i;
int n = str.length();
// Starting point
// of current substring.
int st = 0;
// length of
// current substring.
int currlen = 0;
// maximum length
// substring without
// repeating characters.
int maxlen = 0;
// starting index of
// maximum length substring.
int start = 0;
// Hash Map to store last
// occurrence of each
// already visited character.
HashMap pos = new HashMap();
// Last occurrence of first
// character is index 0;
pos.put(str.charAt(0), 0);
for (i = 1; i < n; i++)
{
// If this character is not present in hash,
// then this is first occurrence of this
// character, store this in hash.
if (!pos.containsKey(str.charAt(i)))
{
pos.put(str.charAt(i), i);
}
else
{
// If this character is present
// in hash then this character
// has previous occurrence,
// check if that occurrence
// is before or after starting
// point of current substring.
if (pos.get(str.charAt(i)) >= st)
{
// find length of current
// substring and update maxlen
// and start accordingly.
currlen = i - st;
if (maxlen < currlen)
{
maxlen = currlen;
start = st;
}
// Next substring will start
// after the last occurrence
// of current character to avoid
// its repetition.
st = pos.get(str.charAt(i)) + 1;
}
// Update last occurrence of
// current character.
pos.replace(str.charAt(i), i);
}
}
// Compare length of last
// substring with maxlen and
// update maxlen and start
// accordingly.
if (maxlen < i - st)
{
maxlen = i - st;
start = st;
}
// The required longest
// substring without
// repeating characters
// is from str[start]
// to str[start+maxlen-1].
return str.substring(start,
start +
maxlen);
}
// Driver Code
public static void main(String[] args)
{
String str = "GEEKSFORGEEKS";
System.out.print(findLongestSubstring(str));
}
}
// This code is contributed by divyeshrabadiya07
Python3
# Python3 program to find and print longest
# substring without repeating characters.
# Function to find and print longest
# substring without repeating characters.
def findLongestSubstring(string):
n = len(string)
# starting point of current substring.
st = 0
# maximum length substring without
# repeating characters.
maxlen = 0
# starting index of maximum
# length substring.
start = 0
# Hash Map to store last occurrence
# of each already visited character.
pos = {}
# Last occurrence of first
# character is index 0
pos[string[0]] = 0
for i in range(1, n):
# If this character is not present in hash,
# then this is first occurrence of this
# character, store this in hash.
if string[i] not in pos:
pos[string[i]] = i
else:
# If this character is present in hash then
# this character has previous occurrence,
# check if that occurrence is before or after
# starting point of current substring.
if pos[string[i]] >= st:
# find length of current substring and
# update maxlen and start accordingly.
currlen = i - st
if maxlen < currlen:
maxlen = currlen
start = st
# Next substring will start after the last
# occurrence of current character to avoid
# its repetition.
st = pos[string[i]] + 1
# Update last occurrence of
# current character.
pos[string[i]] = i
# Compare length of last substring with maxlen
# and update maxlen and start accordingly.
if maxlen < i - st:
maxlen = i - st
start = st
# The required longest substring without
# repeating characters is from string[start]
# to string[start+maxlen-1].
return string[start : start + maxlen]
# Driver Code
if __name__ == "__main__":
string = "GEEKSFORGEEKS"
print(findLongestSubstring(string))
# This code is contributed by Rituraj Jain
C#
// C# program to find
// and print longest substring
// without repeating characters.
using System;
using System.Collections.Generic;
class GFG{
// Function to find and
// print longest substring
// without repeating characters.
public static String findlongestSubstring(String str)
{
int i;
int n = str.Length;
// Starting point
// of current substring.
int st = 0;
// length of
// current substring.
int currlen = 0;
// maximum length
// substring without
// repeating characters.
int maxlen = 0;
// starting index of
// maximum length substring.
int start = 0;
// Hash Map to store last
// occurrence of each
// already visited character.
Dictionary pos = new Dictionary();
// Last occurrence of first
// character is index 0;
pos.Add(str[0], 0);
for (i = 1; i < n; i++)
{
// If this character is not present in hash,
// then this is first occurrence of this
// character, store this in hash.
if (!pos.ContainsKey(str[i]))
{
pos.Add(str[i], i);
}
else
{
// If this character is present
// in hash then this character
// has previous occurrence,
// check if that occurrence
// is before or after starting
// point of current substring.
if (pos[str[i]] >= st)
{
// find length of current
// substring and update maxlen
// and start accordingly.
currlen = i - st;
if (maxlen < currlen)
{
maxlen = currlen;
start = st;
}
// Next substring will start
// after the last occurrence
// of current character to avoid
// its repetition.
st = pos[str[i]] + 1;
}
// Update last occurrence of
// current character.
pos[str[i]] = i;
}
}
// Compare length of last
// substring with maxlen and
// update maxlen and start
// accordingly.
if (maxlen < i - st)
{
maxlen = i - st;
start = st;
}
// The required longest
// substring without
// repeating characters
// is from str[start]
// to str[start+maxlen-1].
return str.Substring(start,
maxlen);
}
// Driver Code
public static void Main(String[] args)
{
String str = "GEEKSFORGEEKS";
Console.Write(findlongestSubstring(str));
}
}
// This code is contributed by shikhasingrajput
Javascript
输出:
EKSFORG
时间复杂度: O(n)
辅助空间: O(n)
如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程和学生竞争性编程现场课程。