📌  相关文章
📜  通过删除 K 个连续的相同字符减少字符串

📅  最后修改于: 2021-10-27 08:23:17             🧑  作者: Mango

给定一个字符串str和一个整数K,任务是通过应用以下操作任意次数来减少字符串,直到不再可能:

最后,打印减少的字符串。

例子:

方法:这个问题可以使用Stack数据结构来解决。请按照以下步骤解决问题:

  • 初始化一个pair的栈,用来存储字符和它们各自的连续频率。
  • 遍历字符串的字符。
  • 如果当前字符是从字符本目前在堆栈的顶部不同,则设置其频率为1。
  • 否则,如果当前字符与堆栈顶部的字符相同,则将其频率增加1
  • 如果堆栈顶部字符的频率为K ,则将其从堆栈中弹出。
  • 最后,将堆栈中剩余的字符打印为结果字符串。

下面是上述方法的实现:

C++
// CPP program for the above approach
#include 
#include 
using namespace std;
 
// Basic Approach is to create a Stack that store the
// Character and its continuous repetition number This is
// done using pair Further we check at each
// iteration, whether the character matches the top of stack
// if it does then check for number of repetitions
// else add to top of stack with count 1
 
class Solution {
public:
    string remove_k_char(int k, string s)
    {
 
        // Base Case
        // If k=1 then all characters
        // can be removed at each
        // instance
        if (k == 1)
            return "";
        // initialize string
        string output = "";
 
        // create a stack using pair<> for storing each
        // character and corresponding
        // repetition
        stack > stk;
 
        // iterate through the string
        for (int i = 0; i < s.length(); i++) {
 
            // if stack is empty then simply add the
            // character with count 1 else check if
            // character is same as top of stack
            if (stk.empty() == true) {
                stk.push(make_pair(s[i], 1));
            }
            else {
 
                // if character at top of stack is same as
                // current character increase the number of
                // repetitions in the top of stack by 1
                if (s[i] == (stk.top()).first) {
                    stk.push(
                        { s[i], stk.top().second + 1 });
                    if (stk.top().second == k) {
                        int x = k;
                        while (x) {
                            stk.pop();
                            x--;
                        }
                    }
                }
                else {
 
                    // if character at top of stack is not
                    // same as current character push the
                    // character along with count 1 into the
                    // top of stack
                    stk.push(make_pair(s[i], 1));
                }
            }
        }
 
        // Iterate through the stack
        // Use string(int,char) in order to replicate the
        // character multiple times and convert into string
        // then add in front of output string
        while (!stk.empty()) {
            output += stk.top().first;
            stk.pop();
        }
        reverse(output.begin(), output.end());
        return output;
    }
};
 
// Driver Code
int main()
{
 
    string s = "geeksforgeeks";
    int k  = 2;
    Solution obj;
    cout << obj.remove_k_char(k, s) << "\n";
 
    return 0;
}
 
// This code has been contributed by Navansh Goel


Java
// Java implementation of the approach
import java.util.*;
 
class GFG {
 
    // Function to find the reduced string
    public static String reduced_String(int k, String s)
    {
        // Base Case
        if (k == 1) {
            String ans = "";
            return ans;
        }
 
        // Creating a stack of type Pair
        Stack st = new Stack();
 
        // Length of the string S
        int l = s.length();
        int ctr = 0;
 
        // iterate through the string
        for (int i = 0; i < l; i++) {
 
            // if stack is empty then simply add the
            // character with count 1 else check if
            // character is same as top of stack
            if (st.size() == 0) {
                st.push(new Pair(s.charAt(i), 1));
                continue;
            }
 
            // if character at top of stack is same as
            // current character increase the number of
            // repetitions in the top of stack by 1
            if (st.peek().c == s.charAt(i)) {
                Pair p = st.peek();
                st.pop();
                p.ctr += 1;
                if (p.ctr == k) {
                    continue;
                }
                else {
                    st.push(p);
                }
            }
            else {
 
                // if character at top of stack is not
                // same as current character push the
                // character along with count 1 into the
                // top of stack
                st.push(new Pair(s.charAt(i), 1));
            }
        }
 
        // iterate through the stack
        // Use string(int,char) in order to replicate the
        // character multiple times and convert into string
        // then add in front of output string
        String ans = "";
        while (st.size() > 0) {
            char c = st.peek().c;
            int cnt = st.peek().ctr;
            while (cnt-- > 0)
                ans = c + ans;
            st.pop();
        }
        return ans;
    }
 
    // Driver code
    public static void main(String[] args)
    {
        int k = 2;
        String st = "geeksforgeeks";
        String ans = reduced_String(k, st);
        System.out.println(ans);
    }
 
    static class Pair {
        char c;
        int ctr;
        Pair(char c, int ctr)
        {
            this.c = c;
            this.ctr = ctr;
        }
    }
}


C#
// C# implementation of the above approach
using System;
using System.Collections.Generic;
public class GFG {
 
    // Function to find the reduced string
    public static String reduced_String(int k, String s)
    {
        // Base Case
        if (k == 1) {
             
            return "";
        }
 
        // Creating a stack of type Pair
        Stack st = new Stack();
 
        // Length of the string S
        int l = s.Length;
      
        // iterate through the string
        for (int i = 0; i < l; i++) {
 
            // if stack is empty then simply add the
            // character with count 1 else check if
            // character is same as top of stack
            if (st.Count == 0) {
                st.Push(new Pair(s[i], 1));
                continue;
            }
 
            // if character at top of stack is same as
            // current character increase the number of
            // repetitions in the top of stack by 1
            if (st.Peek().c == s[i]) {
                Pair p = st.Peek();
                st.Pop();
                p.ctr += 1;
                if (p.ctr == k) {
                    continue;
                }
                else {
                    st.Push(p);
                }
            }
            else {
 
                // if character at top of stack is not
                // same as current character push the
                // character along with count 1 into the
                // top of stack
                st.Push(new Pair(s[i], 1));
            }
        }
 
        // iterate through the stack
        // Use string(int,char) in order to replicate the
        // character multiple times and convert into string
        // then add in front of output string
        String ans = "";
        while (st.Count > 0) {
            char c = st.Peek().c;
            int cnt = st.Peek().ctr;
            while (cnt-- > 0)
                ans = c + ans;
            st.Pop();
        }
        return ans;
    }
 
    // Driver code
    public static void Main(String[] args)
    {
        int k = 2;
        String st = "geeksforgeeks";
        String ans = reduced_String(k, st);
        Console.Write(ans);
    }
 
    public class Pair {
        public char c;
        public int ctr;
        public Pair(char c, int ctr)
        {
            this.c = c;
            this.ctr = ctr;
        }
    }
}
// This code has been contributed by 29AjayKumar


Javascript


C++
#include 
using namespace std;
 
string remove(string s, int k)
{
    // count variable to store the count of each character
    int cnt = 1, n = s.size();
    // to store the output string
    string res = "";
    // to store the char value
    char c = s[0];
    for (int i = 1; i <= n; i++) {
        if (s[i] == s[i - 1]) {
            cnt++;
            if (cnt == k) {
                i++;
                c = s[i];
                cnt = 1;
            }
        }
        else {
            res += (cnt * c);
            c = s[i];
            cnt = 1;
        }
    }
    return res;
}
 
int main()
{
 
    string s = "aabbccd";
    int k = 2;
 
    cout << remove(s, k) << endl;
 
    return 0;
}


输出
gksforgks

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

方法二:

做法:思路是将count和char值存储在变量中,而不是使用栈来提高空间复杂度

C++

#include 
using namespace std;
 
string remove(string s, int k)
{
    // count variable to store the count of each character
    int cnt = 1, n = s.size();
    // to store the output string
    string res = "";
    // to store the char value
    char c = s[0];
    for (int i = 1; i <= n; i++) {
        if (s[i] == s[i - 1]) {
            cnt++;
            if (cnt == k) {
                i++;
                c = s[i];
                cnt = 1;
            }
        }
        else {
            res += (cnt * c);
            c = s[i];
            cnt = 1;
        }
    }
    return res;
}
 
int main()
{
 
    string s = "aabbccd";
    int k = 2;
 
    cout << remove(s, k) << endl;
 
    return 0;
}
输出
d

时间复杂度:O(N)

辅助空间: O(1)