算法设计(打印最长的子字符串而不重复字符)

本文概述

  • C ++
  • Java
  • Python3
  • C#
给定字符串, 请打印最长的子字符串, 而不重复字符。例如, 没有重复字符" ABDEFGABEF"的最长子串是" BDEFGA"和" DEFGAB", 长度为6。对于" BBBB", 最长子串是" B", 长度为1。所需的时间复杂度为O(n ), 其中n是字符串的长度。
先决条件:
最长子串的长度, 不重复字符
例子:
Input : lsbin Output : EKSFORGInput : ABDEFGABEF Output : BDEFGA

【算法设计(打印最长的子字符串而不重复字符)】推荐:请首先在IDE上尝试你的方法, 然后查看解决方案。
方法:
这个想法是遍历字符串, 并且对于每个已经访问过的字符, 将其最后一次出现存储在哈希表中(此处unordered_map用作哈希, 键为字符, 值作为其最后位置)。变量st存储当前子串的起点, maxlen存储最大长度子串??的长度, start存储最大长度子串??的起始索引。在遍历字符串时, 请检查哈希表中是否存在当前字符。如果不存在, 则将当前字符存储在哈希表中, 并将值作为当前索引。如果哈希表中已经存在该字符, 则意味着当前字符可以在当前子字符串中重复。对于此检查, 字符的上一次出现是在当前子字符串的起点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 < bits/stdc++.h> 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< char , int > 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 = "lsbin" ; 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< Character, Integer> pos = new HashMap< Character, Integer> (); // 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 = "lsbin" ; 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 = "lsbin" 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< char , int > pos = new Dictionary< char , int > (); // 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 = "lsbin" ; Console.Write(findlongestSubstring(str)); } } // This code is contributed by shikhasingrajput

输出如下:
EKSFORG

时间复杂度:
O(n)
辅助空间:
O(n)

    推荐阅读