Lexicographically smallest String by eradicating precisely Okay characters

[ad_1]

Given a string S consisting of solely lowercase characters, the duty is to seek out the lexicographically smallest string after eradicating precisely Okay characters from the string. However it’s a must to modify the worth of Okay, i.e., if the size of the string is an influence of two, scale back Okay by half, else multiply Okay by 2. You’ll be able to take away any Okay character.

NOTE: If it isn’t potential to take away Okay (the worth of Okay after correction) characters or if the ensuing string is empty return -1.

Examples:

Enter: S = “fooland”, Okay = 2
Output: “and” 
Rationalization: As the dimensions of the string = 7, which isn’t an influence of two, therefore Okay = 4. After eradicating 4 characters from the given string, the lexicographically smallest string is “and”.

Enter: S = “code”, Okay = 4
Output: “cd”
Rationalization: Because the size of the string = 4,  which is 2 to the facility 2, therefore ok = 2. Therefore, lexicographically smallest string after removing of two characters is “cd”.

Naive Strategy: The essential method to clear up the issue is as follows:

The thought is to seek out the smallest (n – Okay) characters from string utilizing nested loop.

Observe the steps to unravel this downside:

  • First, right the worth of Okay by checking the size of the string is within the energy of two or not.
    • To verify the size of the string is current within the energy of two or not we are able to use the depend of BitSet in size.
    • If the Depend of BitSet is 1 meaning string_length has just one bit which implies it’s within the energy of two.
    • If the dimensions of the string is within the energy of two then divide Okay by 2 else multiply Okay by 2.
  • Now verify if Okay is larger than or equal to the dimensions of the string then return -1. 
  • Else, Initialize an array of measurement string_length with 1 for marking all eliminated(0) and brought(1) parts.
  • Run a loop from 0 to the finish of string_length
    • Run a nested loop contained in the higher loop from the higher loop’s index until index + Okay and discover the smallest character between the vary.
    • Now run a loop from (smallest character index) – 1 until the higher loop index and marks all index with zero – meaning it’s faraway from the string, right here we’ve got to depend the variety of eliminated characters as effectively if it is the same as Okay then cease.
    • Set i = (smallest character index) + 1
  • When come out of the loop verify depend of the eliminated character is lower than Okay then take away that variety of characters from the top of the string and mark that index with zero.
  • Now run a loop from 0 to string_length and verify if the mark of that index is 1 then add the character[i] into the Ans.
  • Return the Ans.

Under is the implementation of the above strategy.

C++

  

#embrace <bits/stdc++.h>

utilizing namespace std;

  

int countSetBits(int n)

{

    int depend = 0;

    whereas (n) {

        depend += n & 1;

        n >>= 1;

    }

    return depend;

}

  

string lexicographicallySmallest(string str, int ok)

{

    int n = str.measurement();

  

    

    

    if (countSetBits(n) == 1)

        ok /= 2;

  

    

    else

        ok *= 2;

  

    

    

    if (ok >= n)

        return "-1";

  

    

    int a[n], i, j;

  

    

    for (i = 0; i < n; i++)

        a[i] = 1;

  

    

    for (i = 0; i < n;) {

  

        

        int begin = i;

  

        

        int index = begin;

  

        

        int finish = min(begin + ok, n - 1);

  

        

        char minn = str[start];

  

        

        for (j = begin + 1; j <= finish; j++) {

  

            

            

            if (str[j] < minn) {

                minn = str[j];

                index = j;

            }

        }

  

        

        for (j = index - 1; j >= begin and ok != 0; j--) {

            a[j] = 0;

            k--;

        }

  

        

        i = index + 1;

    }

  

    

    

    if (ok) {

        for (i = n - 1; i >= 0 and ok != 0; i--) {

            if (a[i]) {

                a[i] = 0;

                k--;

            }

        }

    }

  

    

    string res = "";

  

    

    for (i = 0; i < n; i++) {

        if (a[i]) {

            res += str[i];

        }

    }

  

    

    return res;

}

  

int fundamental()

{

    string S = "fooland";

    int Okay = 2;

  

    

    cout << lexicographicallySmallest(S, Okay) << endl;

  

    return 0;

}

Time Complexity: O(N*N), As right here we run a nested loop.
Auxiliary Area: O(N), utilizing one array for marking all eliminated characters.

Optimized Strategy: To resolve the issue comply with the under concept: 

The thought is to make use of stack and preserve at the very least (n – Okay) non – lowering characters beginning with the smallest character we discovered.

Observe the steps to unravel this downside:

  • First right the worth of Okay by checking the size of the string is within the energy of 2 or not.
    • To verify the size of the string is current within the energy of 2 or not we are able to use the Bitwise-and operator. 
    • If Bitwise-and of string_length and (string_length – 1) provides 0 meaning string_length has just one bit which implies it’s within the energy of two.
    • If the dimensions of the string is within the energy of two then divide Okay by 2 else multiply Okay by 2.
  • Now verify if Okay is larger than or equal to the dimensions of the string then return -1. 
  • Else, create a stack for storing the characters in non-decreasing order.
  • Run a loop and verify for each character:
    • If the highest factor of the stack is larger than the char meaning we’ve got to contemplate the string from right here as a result of we discovered right here lowest character so we’ve got to take away the char from the stack and reduce Okay by one until the stack is empty or the stack high factor is lower than the char and Okay is larger than zero (as a result of we’ve got to take away solely Okay characters).
    • Push the char into the stack
  • Examine if the variety of eliminated chars is lower than Okay then take away that variety of chars from the stack.
  • Copy all stack characters right into a variable string ans and reverse the ans(as a result of we copied from the stack).
  • Return the Ans.

Under is the implementation of the above strategy.

C++

  

#embrace <bits/stdc++.h>

utilizing namespace std;

  

string lexicographicallySmallest(string S, int ok)

{

    string ans = "";

    int l = S.size();

  

    if (l & (l - 1))

        ok += ok;

    else

        ok /= 2;

  

    if (ok >= l)

        return "-1";

  

    stack<char> st;

    for (int i = 0; i < l; i++) {

        whereas (!st.empty() && ok > 0 && st.high() > S[i]) {

            st.pop();

            k--;

        }

        st.push(S[i]);

    }

  

    if (ok > 0)

        whereas (k--)

            st.pop();

  

    whereas (!st.empty()) {

        ans = st.high() + ans;

        st.pop();

    }

    return ans;

}

  

int fundamental()

{

    string S = "fooland";

    int Okay = 2;

  

    

    cout << lexicographicallySmallest(S, Okay);

  

    return 0;

}

Time Complexity: O(N + Okay), for traversal of each factor of the string and contained in the loop we traverse at most Okay instances for the removing of strings from the stack so general time is O(N + Okay).
Auxiliary Area: O(N), For storing characters within the stack.

[ad_2]

Leave a Reply

Your email address will not be published. Required fields are marked *