多米诺骨牌均衡状态| 豆包MarsCode AI刷题

70 阅读4分钟

问题描述

小S玩起了多米诺骨牌,他排列了一行骨牌,并可能将某些骨牌向左或向右推倒。随着骨牌连锁反应的进行,一些骨牌可能因为左右两侧受力平衡而保持竖立。现在小S想要知道在所有动作完成后,哪些骨牌保持竖立。

给定一个表示骨牌初始状态的字符串,其中:

  • "L" 表示该位置的骨牌将向左倒。
  • "R" 表示该位置的骨牌将向右倒。
  • "." 表示该位置的骨牌初始时保持竖立。

模拟整个骨牌倒下的过程,求出最终仍然保持竖立的骨牌的数目和位置。


测试样例

样例1:

输入:num = 14,data = ".L.R...LR..L.." 输出:'4:3,6,13,14'

样例2:

输入:num = 5,data = "R...." 输出:'0'

样例3:

输入:num = 1,data = "." 输出:'1:1'

解题思路

1. 数据结构准备

  • 定义了两个整型数组 t 和 t1,长度都为 num(骨牌的总数)。这两个数组将用于记录在从左到右和从右到左模拟骨牌倒下过程中,每个位置骨牌受到的影响情况。
  • 使用 StringBuffer 类型的 sb 来存储输入的表示骨牌初始状态的字符串,方便后续对字符串中的字符进行修改和操作。

2. 从左到右模拟骨牌倒下(向右传递影响)

  • 通过一个循环从索引 1 到 num - 1 遍历骨牌状态字符串(因为第一个骨牌左侧没有骨牌影响它,所以从第二个开始考虑)。

  • 在每次循环中,检查当前骨牌(索引为 i)及其前一个骨牌(索引为 i - 1)的状态:

    • 如果前一个骨牌是向右倒(sb.charAt(i - 1) == 'R')且当前骨牌是竖立(sb.charAt(i) == '.'),或者前一个骨牌已经受到向右的影响(t[i - 1] > 0)且当前骨牌是竖立,那么当前骨牌会受到向右的影响,将 t[i] 设置为 t[i - 1] + 1,表示当前骨牌受到向右的力的传递影响程度增加了 1

3. 从右到左模拟骨牌倒下(向左传递影响)

  • 接着通过另一个循环从索引 num - 2 到 0 反向遍历骨牌状态字符串(因为最后一个骨牌右侧没有骨牌影响它,所以从倒数第二个开始考虑)。

  • 在每次循环中,检查当前骨牌(索引为 i)及其后一个骨牌(索引为 i + 1)的状态:

    • 如果后一个骨牌是向左倒(sb.charAt(i + 1) == 'L')且当前骨牌是竖立(sb.charAt(i) == '.'),或者后一个骨牌已经受到向左的影响(t1[i + 1] < 0)且当前骨牌是竖立,那么当前骨牌会受到向左的影响,将 t1[i] 设置为 t1[i + 1] - 1,表示当前骨牌受到向左的力的传递影响程度增加了(这里是减少,因为是向左的力,用负数表示) 1

4. 确定最终保持竖立的骨牌

  • 创建两个新的 StringBuffer 类型的变量 s1 和 s2,以及一个整型变量 sums1 将用于存储最终保持竖立的骨牌的位置,sum 用于统计保持竖立的骨牌的数目,s2 将用于构建最终要返回的结果字符串。

  • 通过一个循环从索引 0 到 num - 1 再次遍历骨牌状态字符串。

  • 对于每个位置的骨牌,如果它初始状态是竖立(sb.charAt(i) == '.')并且它受到的向左和向右的影响总和为 0t[i] + t1[i] == 0),说明这个骨牌在整个倒下过程中左右受力平衡,仍然保持竖立。此时:

    • 将该骨牌的位置(索引 i + 1,因为题目可能要求从 1 开始计数位置)添加到 s1 中,并在后面添加逗号作为分隔符。
    • 将 sum 的值增加 1,表示找到一个保持竖立的骨牌。

5. 构建并返回结果

  • 将保持竖立的骨牌的数目 sum、冒号以及存储位置的字符串 s1(去掉最后一个多余的逗号)依次添加到 s2 中。
  • 最后返回 s2 转换为字符串后的结果,这个结果包含了最终保持竖立的骨牌的数目以及它们的位置信息。

解题代码

import java.util.Arrays;

public class Main {
    public static String solution(int num, String data) {
        // Please write your code here
        int i = 0;
        int[] t = new int[num];
        int[] t1 = new int[num];
        StringBuffer sb = new StringBuffer(data);
        for(i = 1; i < num; i++)
        {
            if((sb.charAt(i-1) == 'R' && sb.charAt(i) == '.') || (t[i-1]>0 && sb.charAt(i) == '.')){//sb.replace(i, i+1, "R");
            t[i] = t[i-1] + 1;
            }
        }
        //System.out.println(Arrays.toString(t));
        for(i = num - 2; i >= 0; i--)
        {
            if((sb.charAt(i+1) == 'L' && sb.charAt(i) == '.') || (t1[i+1]<0 && sb.charAt(i) == '.')){//sb.replace(i, i+1, "L");
            t1[i] = t1[i+1] - 1;
            }
        }
        //System.out.println(Arrays.toString(t1));
        StringBuffer s1 = new StringBuffer();
        StringBuffer s2 = new StringBuffer();
        int sum = 0;
        for(i = 0; i < num; i++)
        {
            if(sb.charAt(i) == '.' && t[i]+t1[i] == 0)
            {
                s1.append(i+1).append(',');
                sum++;
            }
        }
        //System.out.println(Arrays.toString(t));
        s2.append(sum).append(':').append(s1);
        s2.deleteCharAt(s2.length()-1);
        return s2.toString();
    }

    public static void main(String[] args) {
        //  You can add more test cases here
        System.out.println(solution(14, ".L.R...LR..L.."));
        System.out.println(solution(5, "R...."));
        System.out.println(solution(1, "."));
    }
}