题目
题意:给出一个长度为n的0、1组成的字符串,分为k个子字符串,使得每个子串没有连续的0、1,求k的最小值和子串的所属编号
思路:使用两个队列s0,s1分别存储0和1的下标(同时两个队列的长度之差也体现了0和1的数量差),遍历字符串:遇见’0’时,若s1为空则必须开辟一个新的子序列来存储这个多出来的’0’,若s1不为空,它就直接放到上一个1所在的子序列的后面,也就是子序列编号相同。遇见’1’时同理
AC代码:
package 练习;
import java.io.*;
import java.math.BigInteger;
import java.util.*;
public class Main {
static Scanner sc=new Scanner(System.in);
public static void main(String[] args) {
for(int t=sc.nextInt();t>0;t--) {
show();
}
}
public static void show() {
int n = sc.nextInt();
String str = sc.next();
char[] arr = str.toCharArray();
int[] ans = new int[n];
int count = 1;
int fin = 0;
Stack<Integer> s1 = new Stack<>();
Stack<Integer> s0 = new Stack<>();
for(int i=0;i<n;i++){
int val = arr[i]-'0';
if(val == 0 && !s1.isEmpty()){//空时放在0面
ans[i] = s1.pop();//移除堆栈顶部的对象,并作为此函数的值返回该对象。
s0.add(ans[i]);
}else if(val == 1 && !s0.isEmpty()){
ans[i] = s0.pop();
s1.add(ans[i]);
}else if(val == 0){
ans[i] = count;
s0.add(count);
count++;
}else if(val == 1){
ans[i]=count;
s1.add(count);
count++;
}
fin = Math.max(fin,count);
}
System.out.println(fin-1);
for(int i=0;i<n;i++){
System.out.print(ans[i]+" ");
}
System.out.println();
}
}