题目描述
时尚圈的衣着稳定性问题
小U在时尚圈组织了一场“校服日”活动,有 n 名学生围成一圈参加活动。每位学生都穿着白色或黑色的校服,白色用 0 表示,黑色用 1 表示。每一天,如果某个学生发现自己和相邻的两位学生穿着相同颜色的校服,那么他会在第二天更换成另一种颜色的校服;否则,他会保持不变。
你的任务是帮助小U判断,在第几天学生们的穿着会达到稳定状态——即某一天后,所有学生的穿着不再发生任何变化。同时,你还需要计算在稳定后,有多少学生的校服颜色与其相邻的同学不同,这些学生被称为“时尚达人”。
最终你需要返回一个包含两个元素的数组:
- 第一个数字表示稳定下来的天数。如果永远无法稳定,则输出
-1。 - 第二个数字表示稳定后成为“时尚达人”的学生人数。如果永远无法稳定,则输出
-1。
解题思路
这个题目需要解决两个问题,第一个是学生们的穿着需要在第几天才稳定,第二个问题是最后有多少个人是“时尚达人”。第二个问题比较好解决,只需要在最后遍历数组,判断一下与前后同学都不同的人数就行。
第一个问题就相对麻烦一点,首先要考虑什么时候会存在无法稳定的情况,观察发现,如果所有同学都需要在第二天换另一种颜色的衣服,那么第三天的衣服又会是第一天的情况,因此这样的情况就永远无法稳定,因为永远都是同学们穿一样的衣服的颜色。
因此我们可以首先遍历找出需要换衣服的所有同学,如果为0或者全部,那么就不需要考虑了,为0则代表只需要第一天就可以稳定,为全部人数,则代表无法稳定下来。
如果不是这两种情况,那么就需要进入到第二天,第二天的时候就已经在前一天的情况下换衣服了,同时还需要遍历一遍数组看是否还有人需要换衣服,如果有继续进入到下一天,如果没有则循环结束。
解题代码
public class Main {
public static int[] solution(int n, String data) {
// Edit your code here
int[] result = new int[]{-1,-1};
StringBuffer tmp = new StringBuffer(data);
int changes = 0;
int days = 0;
for(int i=0;i<n;i++){
if(i==0){
if(tmp.charAt(0) == tmp.charAt(n-1) && tmp.charAt(0) == tmp.charAt(1)){
changes++;
}
}else if(i == n-1){
if(tmp.charAt(n-1) == tmp.charAt(n-2) && tmp.charAt(n-1) == tmp.charAt(0)){
changes++;
}
}else{
if(tmp.charAt(i) == tmp.charAt(i+1) && tmp.charAt(i) == tmp.charAt(i-1)){
changes++;
}
}
}
System.out.println(changes);
if(changes == n){
return result;
}
days++;
while(changes != 0){
changes = 0;
StringBuffer k = new StringBuffer(tmp.toString());
System.out.println(tmp.toString());
for(int i=0;i<n;i++){
if(i==0){
if(tmp.charAt(0) == tmp.charAt(n-1) && tmp.charAt(0) == tmp.charAt(1)){
if(tmp.charAt(0) == '0'){
k.setCharAt(0,'1');
}else{
k.setCharAt(0,'0');
}
//changes++;
}
}else if(i == n-1){
if(tmp.charAt(n-1) == tmp.charAt(n-2) && tmp.charAt(n-1) == tmp.charAt(0)){
if(tmp.charAt(n-1) == '0'){
k.setCharAt(n-1,'1');
}else{
k.setCharAt(n-1,'0');
}
//changes++;
}
}else{
if(tmp.charAt(i) == tmp.charAt(i+1) && tmp.charAt(i) == tmp.charAt(i-1)){
if(tmp.charAt(i) == '0'){
k.setCharAt(i,'1');
}else{
k.setCharAt(i,'0');
}
//changes++;
}
}
}
System.out.println(tmp.toString());
tmp = k;
days++;
for(int i=0;i<n;i++){
if(i==0){
if(tmp.charAt(0) == tmp.charAt(n-1) && tmp.charAt(0) == tmp.charAt(1)){
changes++;
}
}else if(i == n-1){
if(tmp.charAt(n-1) == tmp.charAt(n-2) && tmp.charAt(n-1) == tmp.charAt(0)){
changes++;
}
}else{
if(tmp.charAt(i) == tmp.charAt(i+1) && tmp.charAt(i) == tmp.charAt(i-1)){
changes++;
}
}
}
}
//System.out.println(tmp.toString());
result[1] = 0;
for(int i=0;i<n;i++){
if(i==0){
if(tmp.charAt(0) != tmp.charAt(n-1) && tmp.charAt(0) != tmp.charAt(1)){
//System.out.println(result[1]);
result[1]++;
}
}else if(i == n-1){
if(tmp.charAt(n-1) != tmp.charAt(n-2) && tmp.charAt(n-1) != tmp.charAt(0)){
//System.out.println(result[1]);
result[1]++;
}
}else{
if(tmp.charAt(i) != tmp.charAt(i+1) && tmp.charAt(i) != tmp.charAt(i-1)){
//System.out.println(result[1]);
result[1]++;
}
}
}
result[0] = days;
return result;
}
public static void main(String[] args) {
// Add your test cases here
//System.out.println(java.util.Arrays.equals(solution(4, "0000"), new int[]{-1, -1}));
//System.out.println(java.util.Arrays.equals(solution(4, "1110"), new int[]{2, 4}));
System.out.println(solution(21, "001000001101001101110")[0]);
}
}
总结
这个问题有一个需要注意的点就是,因为我们每次对数据修改,也就是同学换衣服时都是依据上一天没修改的状态作为参考来的,因此修改的时候应该有两种状态,即未修改前的状态,和要修改的状态,未修改的状态用来判断,只有要修改的状态才能修改。也就是说我们每次循环的时候需要对当前穿衣状态做一个备份用来修改,判断的时候仍然用前一天的穿衣情况判断。