如何使用O(1)额外空间从字符串中删除重复项()

本文概述

  • C ++
  • Java
  • Python3
  • C#
  • 的PHP
  • Java
  • Python3
  • C#
给定一个字符串str对于小写字符, 任务是删除重复项并返回结果字符串, 而无需修改原始字符串中字符的顺序。
例子:
Input: str = "lsbinforlsbin" Output: lsbinforInput: str = "characters" Output: chartes

方法:这个想法是使用计数器变量以标记字符串中是否存在字符。要标记" a"的存在, 请将第0位设置为1, 为" b"将第1位设置为1, 依此类推。如果原始字符串中存在的字符的相应位设置为0, 则表示它是该字符的首次出现, 因此将其相应位设置为1, 并继续在结果字符串中包括当前字符。
【如何使用O(1)额外空间从字符串中删除重复项()】考虑字符串str =" lsbinforlsbin"
字符:'g'
x = 6(g – 97的ascii)计数器中的第6位未设置, 导致首次出现字符'g'。
str [0] ='g'
计数器= 00000000000000000000000001000000 //将第6位标记为已访问
长度= 1
字符:'e'
x = 4(e – 97的ascii)
计数器中的第4位未设置, 导致首次出现字符'e '。
str [1] =‘e’
计数器= 00000000000000000000000001010000 //将第4位标记为已访问
长度= 2
字符:‘e’
x = 4(e – 97的ascii)
设置计数器的第4位将导致重复字符。
忽略此字符。移动到下一个字符。
计数器= 00000000000000000000000001010000 //与先前的
长度= 2
字符相同:'k'
x = 10(k的ascii – 97)计数器中的第10位未设置, 导致首次出现字符'k'。
str [2] ='k'
计数器= 00000000000000000000010001010000 //将第10位标记为已访问
长度= 3
类似地, 对所有字符都执行相同的操作。
结果字符串:lsbinfor(从索引0开始的长度为7的字符串)
算法: 
  1. 初始化一个计数器变量(保持跟踪字符串中访问的字符), 它是一个32位整数, 最初表示为(00000000000000000000000000000000)。
  2. 假设" a"为计数器的第0位, " b"为计数器的第1位, " c"为计数器的第2位, 依此类推。
  3. 遍历输入字符串的每个字符。
  4. 获取角色的值, 其中角色的值(x)=角色的Ascii –97。这将确保将'a'的值设置为0, 将'b'的值设置为1, 依此类推。
  5. 检查计数器的第x位。
  6. 如果计数器的第X位为0, 则表示当前字符是第一次出现, 请将当前字符保留在string的"长度"索引处。
  7. 通过设置计数器的第x位来标记当前访问的字符。
  8. 增量长度。
  9. 从索引0返回大小为"长度"的子字符串。
下面是上述方法的实现:
C ++
// C++ implementation of above approach #include < bits/stdc++.h> #include < string> using namespace std; // Function to remove duplicates string removeDuplicatesFromString(string str) { // keeps track of visited characters int counter = 0; int i = 0; int size = str.size(); // gets character value int x; // keeps track of length of resultant string int length = 0; while (i < size) { x = str[i] - 97; // check if Xth bit of counter is unset if ((counter & (1 < < x)) == 0) { str[length] = 'a' + x; // mark current character as visited counter = counter | (1 < < x); length++; } i++; } return str.substr(0, length); } // Driver code int main() { string str = "lsbinforlsbin" ; cout < < removeDuplicatesFromString(str); return 0; }

Java
// Java implementation of above approach import java.util.Arrays; class GFG { // Function to remove duplicates static char [] removeDuplicatesFromString(String string) { // keeps track of visited characters int counter = 0 ; char [] str = string.toCharArray(); int i = 0 ; int size = str.length; // gets character value int x; // keeps track of length of resultant String int length = 0 ; while (i < size) { x = str[i] - 97 ; // check if Xth bit of counter is unset if ((counter & ( 1 < < x)) == 0 ) { str[length] = ( char )( 'a' + x); // mark current character as visited counter = counter | ( 1 < < x); length++; } i++; } return Arrays.copyOfRange(str, 0 , length); } // Driver code public static void main(String[] args) { String str = "lsbinforlsbin" ; System.out.println(removeDuplicatesFromString(str)); } } // This code is contributed by Mithun Kumar

Python3
# Python3 implementation of above approach # Function to remove duplicates def removeDuplicatesFromString(str2): # keeps track of visited characters counter = 0 ; i = 0 ; size = len (str2); str1 = list (str2); # gets character value x = 0 ; # keeps track of length of resultant string length = 0 ; while (i < size): x = ord (str1[i]) - 97 ; # check if Xth bit of counter is unset if ((counter & ( 1 < < x)) = = 0 ): str1[length] = chr ( 97 + x); # mark current character as visited counter = counter | ( 1 < < x); length + = 1 ; i + = 1 ; str2 = ''.join(str1); return str2[ 0 :length]; # Driver code str1 = "lsbinforlsbin" ; print (removeDuplicatesFromString(str1)); # This code is contributed by mits

C#
// C# implementation of above approach using System; class GFG { // Function to remove duplicates static string removeDuplicatesFromString( string string1) { // keeps track of visited characters int counter = 0; char [] str = string1.ToCharArray(); int i = 0; int size = str.Length; // gets character value int x; // keeps track of length of resultant String int length = 0; while (i < size) { x = str[i] - 97; // check if Xth bit of counter is unset if ((counter & (1 < < x)) == 0) { str[length] = ( char )( 'a' + x); // mark current character as visited counter = counter | (1 < < x); length++; } i++; } return ( new string (str)).Substring(0, length); } // Driver code static void Main() { string str = "lsbinforlsbin" ; Console.WriteLine(removeDuplicatesFromString(str)); } } // This code is contributed by mits

的PHP
< ?php // PHP implementation of above approach // Function to remove duplicates function removeDuplicatesFromString( $str ) { // keeps track of visited characters $counter = 0; $i = 0; $size = strlen ( $str ); // gets character value $x = 0; // keeps track of length of resultant string $length = 0; while ( $i < $size ) { $x = ord( $str [ $i ]) - 97; // check if Xth bit of counter is unset if (( $counter & (1 < < $x )) == 0) { $str [ $length ] = chr (97 + $x ); // mark current character as visited $counter = $counter | (1 < < $x ); $length ++; } $i ++; } return substr ( $str , 0, $length ); } // Driver code $str = "lsbinforlsbin" ; echo removeDuplicatesFromString( $str ); // This code is contributed by mits ?>

输出如下:
lsbinfor

时间复杂度:O(n)
空间复杂度:O(n)->由于它使用char []字符串数组来存储字符串字符(即取决于输入字符串的长度)
另一种方法:这种方法通过一个大小为256的整数数组(所有可能的字符)跟踪给定输入字符串中已访问的字符。
这个想法如下:
  1. 创建一个大小为256的整数数组, 以便跟踪所有可能的字符。
  2. 遍历输入字符串和每个字符:
  3. 使用ASCII码字符值作为索引:
    • 如果index处的值为0, 则将字符复制到原始输入数组中并增加endIndex, 同时将index处的值更新为-1。
    • 否则跳过角色。
下面是上述方法的实现:
Java
//Java implementation of above approach import java.util.Arrays; class GFG { // Method to remove duplicates static char [] removeDuplicatesFromString(String string) { //table to keep track of visited characters int [] table = new int [ 256 ]; char [] chars = string.toCharArray(); //to keep track of end index of resultant string int endIndex = 0 ; for ( int i = 0 ; i < chars.length; i++) { if (table[chars[i]] == 0 ) { table[chars[i]] = - 1 ; chars[endIndex++] = chars[i]; } }return Arrays.copyOfRange(chars, 0 , endIndex); } // Driver code public static void main(String[] args) { String str = "lsbinforlsbin" ; System.out.println(removeDuplicatesFromString(str)); } } // This code is contributed by Sonu Singh

Python3
# Python3 implementation of above approach # Method to remove duplicates def removeDuplicatesFromString(string):# Table to keep track of visited # characters table = [ 0 for i in range ( 256 )]# To keep track of end index # of resultant string endIndex = 0 string = list (string)for i in range ( len (string)): if (table[ ord (string[i])] = = 0 ): table[ ord (string[i])] = - 1 string[endIndex] = string[i] endIndex + = 1ans = "" for i in range (endIndex): ans + = string[i]return ans # Driver code if __name__ = = '__main__' :temp = "lsbinforlsbin"print (removeDuplicatesFromString(temp))# This code is contributed by Kuldeep Singh

C#
// C# implementation of above approach using System; class GFG { // Method to remove duplicates static char [] removeDuplicatesFromString(String str) { // table to keep track of visited characters int [] table = new int [256]; char [] chars = str.ToCharArray(); // to keep track of end index // of resultant string int endIndex = 0; for ( int i = 0; i < chars.Length; i++) { if (table[chars[i]] == 0) { table[chars[i]] = -1; chars[endIndex++] = chars[i]; } } char []newStr = new char [endIndex]; Array.Copy(chars, newStr, endIndex); return newStr; } // Driver code public static void Main(String[] args) { String str = "lsbinforlsbin" ; Console.WriteLine(removeDuplicatesFromString(str)); } } // This code is contributed by 29AjayKumar

输出如下:
lsbinfor

时间复杂度:O(n)
空间复杂度:O(n)-> 由于它使用char []字符串数组来存储字符串字符(即取决于输入字符串的长度)

    推荐阅读