📌  相关文章
📜  从O(1)多余空间中的字符串中删除重复项

📅  最后修改于: 2021-04-23 16:36:16             🧑  作者: Mango

给定一个由小写字符的字符串str ,任务是删除重复项并返回结果字符串,而无需修改原始字符串的字符顺序。

例子:

Input: str = "geeksforgeeks"
Output: geksfor

Input: str = "characters"
Output: chartes

方法:想法是使用计数器变量的位来标记字符串字符的存在。要标记“ a”的存在,请将第0位设置为1,为“ b”将第1位设置为1,依此类推。如果原始字符串存在的相应字符位设置为0,则表示它是该字符的首次出现,因此将其相应位设置为1并继续在结果字符串包括当前字符。

算法:

  1. 初始化计数器变量(跟踪在字符串访问的字符),它是一个32位整数初始表示为(00000000000000000000000000000000)。
  2. 将“ a”视为计数器的第0位,将“ b”视为计数器的第1位,将“ c”视为计数器的第2位,依此类推。
  3. 遍历输入字符串的每个字符。
  4. 获得字符的值,其中人物的值(X)=字符的Ascii码- 97.这将确保为“A”值为0,“B”的价值为1,依此类推。
  5. 检查计数器的第x位。
  6. 如果计数器的第X位为0,这表示当前字符是第一次出现,请将当前字符保留在字符串的“长度”索引处。
  7. 通过设置计数器的第x位来标记当前访问的字符。
  8. 增量长度。
  9. 从索引0返回大小为“长度”的子字符串。

下面是上述方法的实现:

C++
// C++ implementation of above approach
#include 
#include 
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 = "geeksforgeeks";
    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 = "geeksforgeeks";
        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 = "geeksforgeeks";
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 = "geeksforgeeks";
        Console.WriteLine(removeDuplicatesFromString(str));
    }
}
 
// This code is contributed by mits


PHP


C++
// C++ implementation of above approach
#include 
using namespace std;
 
// Method to remove duplicates
string removeDuplicatesFromString(string str)
{
     
    // Table to keep track of visited characters
    vector table(256, 0);
    vector chars;
     
    for(auto i : str)
        chars.push_back(i);
     
    // To keep track of end index of
    // resultant string
    int endIndex = 0;
     
    for(int i = 0; i < chars.size(); i++)
    {
        if (table[chars[i]] == 0)
        {
            table[chars[i]] = -1;
            chars[endIndex++] = chars[i];
        }
    }
     
    string ans = "";
     
    for(int i = 0; i < endIndex; i++)
        ans += chars[i];
     
    return ans;
}
 
// Driver code
int main()
{
    string str = "geeksforgeeks";
     
    cout << (removeDuplicatesFromString(str))
         << endl;
}
 
// This code is contributed by Mohit kumar 29


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 = "geeksforgeeks";
        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 += 1
             
    ans = ""
    for i in range(endIndex):
      ans += string[i]
       
    return ans
 
# Driver code
if __name__ == '__main__':
     
    temp = "geeksforgeeks"
     
    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 = "geeksforgeeks";
        Console.WriteLine(removeDuplicatesFromString(str));
    }
}
 
// This code is contributed by 29AjayKumar


输出:
geksfor

时间复杂度: O(n)
空间复杂度:O(N) – >作为它使用char []字符串的数组字符串的存储字符(即依赖于输入的字符串的长度)

另一种方法:该方法通过大小为256整数数组(所有可能的字符),跟踪给定输入字符串中访问的字符。
这个想法如下:

  1. 创建一个大小为256的整数数组,以便跟踪所有可能的字符。
  2. 遍历输入字符串,并针对每个字符:
  3. 查找与字符作为索引的ASCII值的数组:
    • 如果index处的值为0,则将字符复制到原始输入数组中,并增加endIndex,同时将index处的值更新为-1。
    • 否则跳过字符。

下面是上述方法的实现:

C++

// C++ implementation of above approach
#include 
using namespace std;
 
// Method to remove duplicates
string removeDuplicatesFromString(string str)
{
     
    // Table to keep track of visited characters
    vector table(256, 0);
    vector chars;
     
    for(auto i : str)
        chars.push_back(i);
     
    // To keep track of end index of
    // resultant string
    int endIndex = 0;
     
    for(int i = 0; i < chars.size(); i++)
    {
        if (table[chars[i]] == 0)
        {
            table[chars[i]] = -1;
            chars[endIndex++] = chars[i];
        }
    }
     
    string ans = "";
     
    for(int i = 0; i < endIndex; i++)
        ans += chars[i];
     
    return ans;
}
 
// Driver code
int main()
{
    string str = "geeksforgeeks";
     
    cout << (removeDuplicatesFromString(str))
         << endl;
}
 
// This code is contributed by Mohit kumar 29

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 = "geeksforgeeks";
        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 += 1
             
    ans = ""
    for i in range(endIndex):
      ans += string[i]
       
    return ans
 
# Driver code
if __name__ == '__main__':
     
    temp = "geeksforgeeks"
     
    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 = "geeksforgeeks";
        Console.WriteLine(removeDuplicatesFromString(str));
    }
}
 
// This code is contributed by 29AjayKumar
输出:
geksfor

时间复杂度: O(n)
空间复杂度:O(N) – >作为它使用char []字符串的数组字符串的存储字符(即依赖于输入的字符串的长度)
该方法由Sonu Singh贡献。