📌  相关文章
📜  字典上最小的二进制字符串,通过翻转索引处不可整除 K1 或 K2 的位而形成,使得 1 的计数始终大于从左侧算起的 0

📅  最后修改于: 2022-05-13 01:56:05.111000             🧑  作者: Mango

字典序上最小的二进制字符串,通过翻转索引处不可整除 K1 或 K2 的位而形成,使得 1 的计数始终大于从左侧算起的 0

给定一个大小为N的二进制字符串S (基于 1 的索引)和两个正整数K1K2 ,任务是通过翻转不能被K1K2整除的索引处的字符来找到字典顺序上最小的字符串,使得1s的计数,直到每个可能的索引始终大于0s的计数。如果不可能形成这样的字符串,则打印“-1”

例子:

方法:可以通过从左到右修改每个解锁位置的字符串S来解决该问题,如果可以使0则将其转换为0否则将其转换为1 。请按照以下步骤解决问题:

  • 初始化两个变量c1c0分别存储10的计数。
  • 初始化一个向量pos[] ,它存储所有不能被K1K2整除的0的位置。
  • 遍历给定的字符串S并执行以下步骤:
    • 如果字符为0 ,则增加c0的值。否则,增加c1的值。
    • 如果当前索引不能被K1K2整除,则将此索引插入向量pos[]中。
    • 如果在任何索引i处, 0的计数变得大于或等于1 ,则:
      • 如果向量为空,则无法将字符串修改为所需的组合。因此,打印-1
      • 否则,弹出向量中存在的最后一个位置,并将 c0 的值更新为c0 – 1 ,将c1的值更新为c1 + 1S[pos] = '1'
  • 完成上述步骤后,打印字符串S修改后的字符串。

下面是上述方法的实现:

C++
// C++ program for the above approach
 
#include 
using namespace std;
 
// Function to find lexicographically
// smallest string having number of 1s
// greater than number of 0s
void generateString(int k1, int k2, string s)
{
    // C1s And C0s stores the count of
    // 1s and 0s at every position
    int C1s = 0, C0s = 0;
    int flag = 0;
    vector pos;
 
    // Traverse the string S
    for (int i = 0; i < s.length(); i++) {
 
        if (s[i] == '0') {
            C0s++;
 
            // If the position is not
            // divisible by k1 and k2
            if ((i + 1) % k1 != 0
                && (i + 1) % k2 != 0) {
                pos.push_back(i);
            }
        }
 
        else {
            C1s++;
        }
 
        if (C0s >= C1s) {
 
            // If C0s >= C1s and pos[] is
            // empty then the string can't
            // be formed
            if (pos.size() == 0) {
                cout << -1;
                flag = 1;
                break;
            }
 
            // If pos[] is not empty then
            // flip the bit of last position
            // present in pos[]
            else {
                int k = pos.back();
                s[k] = '1';
                C0s--;
                C1s++;
                pos.pop_back();
            }
        }
    }
 
    // Print the result
    if (flag == 0) {
        cout << s;
    }
}
 
// Driver Code
int main()
{
    int K1 = 2, K2 = 4;
    string S = "11000100";
    generateString(K1, K2, S);
 
    return 0;
}


Java
// Java program for the above approach
import java.util.*;
 
class GFG
{
 
// Function to find lexicographically
// smallest String having number of 1s
// greater than number of 0s
static void generateString(int k1, int k2, char[] s)
{
   
    // C1s And C0s stores the count of
    // 1s and 0s at every position
    int C1s = 0, C0s = 0;
    int flag = 0;
    Vector pos = new Vector();
 
    // Traverse the String S
    for (int i = 0; i < s.length; i++) {
 
        if (s[i] == '0') {
            C0s++;
 
            // If the position is not
            // divisible by k1 and k2
            if ((i + 1) % k1 != 0
                && (i + 1) % k2 != 0) {
                pos.add(i);
            }
        }
 
        else {
            C1s++;
        }
 
        if (C0s >= C1s) {
 
            // If C0s >= C1s and pos[] is
            // empty then the String can't
            // be formed
            if (pos.size() == 0) {
                System.out.print(-1);
                flag = 1;
                break;
            }
 
            // If pos[] is not empty then
            // flip the bit of last position
            // present in pos[]
            else {
                int k = pos.get(pos.size()-1);
                s[k] = '1';
                C0s--;
                C1s++;
                pos.remove(pos.size() - 1);
            }
        }
    }
 
    // Print the result
    if (flag == 0) {
        System.out.print(s);
    }
}
 
// Driver Code
public static void main(String[] args)
{
    int K1 = 2, K2 = 4;
    String S = "11000100";
    generateString(K1, K2, S.toCharArray());
 
}
}
 
// This code is contributed by 29AjayKumar


Python3
# Python 3 program for the above approach
 
# Function to find lexicographically
# smallest string having number of 1s
# greater than number of 0s
def generateString(k1, k2, s):
   
    # C1s And C0s stores the count of
    # 1s and 0s at every position
    s = list(s)
    C1s = 0
    C0s = 0
    flag = 0
    pos = []
 
    # Traverse the string S
    for i in range(len(s)):
        if (s[i] == '0'):
            C0s += 1
 
            # If the position is not
            # divisible by k1 and k2
            if ((i + 1) % k1 != 0 and (i + 1) % k2 != 0):
                pos.append(i)
 
        else:
            C1s += 1
 
        if (C0s >= C1s):
            # If C0s >= C1s and pos[] is
            # empty then the string can't
            # be formed
            if (len(pos) == 0):
                print(-1)
                flag = 1
                break
 
            # If pos[] is not empty then
            # flip the bit of last position
            # present in pos[]
            else:
                k = pos[len(pos)-1]
                s[k] = '1'
                C0s -= 1
                C1s += 1
                pos = pos[:-1]
 
    # Print the result
    s = ''.join(s)
    if (flag == 0):
        print(s)
 
# Driver Code
if __name__ == '__main__':
    K1 = 2
    K2 = 4
    S = "11000100"
    generateString(K1, K2, S)
     
    # This code is contributed by SURENDRA_GANGWAR.


C#
// C# program for the above approach
using System;
using System.Collections.Generic;
 
class GFG {
 
// Function to find lexicographically
// smallest String having number of 1s
// greater than number of 0s
static void generateString(int k1, int k2, char[] s)
{
    
    // C1s And C0s stores the count of
    // 1s and 0s at every position
    int C1s = 0, C0s = 0;
    int flag = 0;
    List pos = new List();
  
    // Traverse the String S
    for (int i = 0; i < s.Length; i++) {
  
        if (s[i] == '0') {
            C0s++;
  
            // If the position is not
            // divisible by k1 and k2
            if ((i + 1) % k1 != 0
                && (i + 1) % k2 != 0) {
                pos.Add(i);
            }
        }
  
        else {
            C1s++;
        }
  
        if (C0s >= C1s) {
  
            // If C0s >= C1s and pos[] is
            // empty then the String can't
            // be formed
            if (pos.Count == 0) {
                Console.WriteLine(-1);
                flag = 1;
                break;
            }
  
            // If pos[] is not empty then
            // flip the bit of last position
            // present in pos[]
            else {
                int k = pos[(pos.Count - 1)];
                s[k] = '1';
                C0s--;
                C1s++;
                pos.Remove(pos.Count - 1);
            }
        }
    }
  
    // Print the result
    if (flag == 0) {
        Console.WriteLine(s);
    }
}
 
    // Driver Code
    public static void Main()
    {
    int K1 = 2, K2 = 4;
    string S = "11000100";
    generateString(K1, K2, S.ToCharArray());
    }
}
 
// This code is contributed by avijitmondal1998.


Javascript


输出:
11100110

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