首页 > 试题广场 >

推倒多米诺骨牌

[编程题]推倒多米诺骨牌
  • 热度指数:559 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 256M,其他语言512M
  • 算法知识视频讲解


一行中有张多米诺骨牌,我们将每张多米诺骨牌垂直竖立。
在开始时,我们同时把一些多米诺骨牌向左或向右推。

每过一秒,倒向左边的多米诺骨牌会推动其左侧相邻的多米诺骨牌。
同样地,倒向右边的多米诺骨牌也会推动竖立在其右侧的相邻多米诺骨牌。
如果同时有多米诺骨牌落在一张垂直竖立的多米诺骨牌的两边,由于受力平衡,该骨牌仍然保持不变。
就这个问题而言,我们会认为正在下降的多米诺骨牌不会对其它正在下降或已经下降的多米诺骨牌施加额外的力。
给定表示初始状态的字符串"S" 。如果第 i 张多米诺骨牌被推向左边,则 S[i] = 'L';如果第 i 张多米诺骨牌被推向右边,则 S[i] = 'R';如果第 i 张多米诺骨牌没有被推动,则 S[i] = '.'。
返回表示最终状态的字符串。


示例1

输入

"..LR.."

输出

"LLLRRR"

说明

左边三个都往左倒,右边三个都往右倒
示例2

输入

"R...L"

输出

"RR.LL"

说明

左边2个都往左倒,右边2个都往右倒,中间的保持不变

备注:
class Solution:
    def fill(self, arr, x, y, mode='RL'):
        if x<y:
            if mode=='RL':
                mid=(x+y)//2
                if (y-x)%2==0:
                    arr[x:mid]=['R']*(mid-x)
                    arr[mid+1:y+1]=['L']*(mid-x)
                else:
                    arr[x:mid+1]=['R']*(mid-x+1)
                    arr[mid+1:y+1]=['L']*(mid-x+1)
            elif mode=='LL':
                arr[x:y]=['L']*(y-x)
            elif mode=='RR':
                arr[x:y]=['R']*(y-x)
        return arr
    def solve(self, s ):
        # write code here
        arr=list(s)
        count=0
        last_c=''
        last_i=0
        for i, c in enumerate(arr):
            if c!='.':
                if count==0:
                    count+=1
                    if c=='L':
                        arr=self.fill(arr, 0, i, 'LL')
                else:
                    arr=self.fill(arr, last_i, i, last_c+c)
                last_i, last_c=i, c
        if last_c=='R':
            arr=self.fill(arr, last_i, len(s), 'RR')
        return ''.join(arr) 
最前面和最后面要特殊处理,其他的按照不同模式来填充
发表于 2021-09-24 23:34:24 回复(0)
// 字符串替换法

function solve( s ) {
    // write code here
    return s.replace(/R\.+L/g, str => {
        let len = str.length
        let halfLen = parseInt(len / 2)
        let middle = len % 2 !== 0 ? '#' : ''
        // 如果长度为奇数 中间那位用 # 表示,最后再替换回来
        return 'R'.repeat(halfLen) + middle + 'L'.repeat(halfLen)
    })
    .replace(/R\.+/g, str => 'R'.repeat(str.length))
    .replace(/\.+L/g, str => 'L'.repeat(str.length))
    .replace(/#/g, '.')
}

发表于 2021-08-10 12:59:58 回复(1)

我的思路是这样的:

  1. 将字符串拆分成字符数组
  2. 查找里面 L 和 R 的位置
  3. 如果:L 在 R 的右侧,则执行
    3.1 查找 L 和 R 的中间位置 center
    3.2 将 center 往右、L 往左的元素设置为 L
    3.3 将 center 往左、R 往右的元素设置为 R
  4. L 在 R 的左侧,执行:
    4.1 将 0 往右、L 往左的元素设置为 L
    4.2 将 R 往右、最后一个元素及其往前的元素设置为 R

这样的思路能满足题目示例的用例,但最后一个测试用例都没有过得了,求大佬指点 /bq/bq

function solve( s ) {
  const arr = s.split("");
  const LIndex = arr.findIndex(item => item === "L");
  const RIndex = arr.findIndex(item => item === "R");

  if (LIndex > RIndex) {
    const center = (LIndex - RIndex) / 2 + RIndex;
    for(let i = RIndex + 1; i < center; i++) {
      arr[i] = "R";
    }
    for(let i = LIndex - 1; i > center; i--) {
      arr[i] = "L";
    }
  } else {
    for(let i = 0; i < LIndex; i++) {
      arr[i] = "L";
    }
    for(let i = RIndex; i < arr.length; i++) {
      arr[i] = "R";
    }
  }
  return arr.join("");
}
module.exports = {
    solve : solve
};
发表于 2021-06-23 22:45:19 回复(4)
//暴力解法
function solve( s ) {
    // write code here
    var arr = s.split("")
    var flag_l = -1;
    var flag_r = -1;
    for(let i = 0; i < arr.length; i ++) {
        if(arr[i]==='R'&&flag_r===-1) flag_r = i;
        else if(arr[i]==='L'&&flag_l===-1) flag_l = i;
        //遇到L之前都没有遇到R
        if(flag_l!==-1&&flag_r===-1) {
            while(flag_l>=0&&arr[--flag_l]==='.') {
                arr[flag_l] = 'L'
            }
            flag_l = -1;
        }
        //遇到R直到结束都没有再次遇到L
        else if(flag_r!==-1&&flag_l===-1&&i===arr.length-1) {
            while(flag_r<arr.length) {
                arr[flag_r++] = 'R'
            }
        }
        //先遇到R在遇到L
        else if(flag_l!==-1&&flag_r!==-1) {
            
            while(flag_r < flag_l) {
                arr[flag_r++] = 'R'
                arr[flag_l--] = 'L'
            }
            flag_l = -1;
            flag_r = -1;
        }
        //先遇到R遭遇到R
        else if(arr[i]==='R'&&flag_r!==-1&&flag_l===-1) {
            while(flag_r < i) {
                arr[flag_r++] = 'R'
            }
            flag_r = i;
        }
    }
    let result = ''
    arr.forEach(value => {
        result+=value
    });
    return result
}
编辑于 2024-03-10 17:44:19 回复(0)
#include <vector>
class Solution {
public:
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 
     * @param s string字符串 
     * @return string字符串
     */
    string solve(string s) {
        // write code here
        vector<vector<int> > typeVec;
        int l=-1,r=-1;

        for (int i=0;i<s.size();i++){
            if (s[i]=='L'){
                if (r>=0){
                    l=i;
                    vector<int> vec = {0,r,l};
                    typeVec.push_back(vec);
                    r=-1;
                    l=-1;
                }
                else{
                    l = i;
                    vector<int> vec = {1, l};
                    typeVec.push_back(vec);
                    l = -1;
                }
            }
            else if (s[i]=='R'){
                if (r<0) r = i;
                else{
                    vector<int> vec = {2, r};
                    typeVec.push_back(vec);
                    r = i;
                }
            }
            else if (i==s.size()-1 && r>0){
                vector<int> vec = {2, r};
                typeVec.push_back(vec);
            }
        }

        for (int i=0; i<typeVec.size(); i++){
            if (typeVec[i][0]==0){ // RL
                int r=typeVec[i][1], l=typeVec[i][2];
                while (l>r && r!=s.size()){
                    s[r++] = 'R';
                    if (l>0){
                        s[l--]='L';
                    }
                }
            }
            else if (typeVec[i][0]==1){ // L
                int idx = typeVec[i][1] - 1;
                while (idx>=0 && s[idx]=='.') s[idx--] = 'L';
            }
            else if (typeVec[i][0]==2){ // R
                int idx = typeVec[i][1] + 1;
                while (idx<s.size() && s[idx]=='.') s[idx++] = 'R';
            }
        }
        return s;
    }
};
用c++的前端选手在此..这个题目不难,主要是要考虑到可能同时推倒不止2堆骨牌.
有三种情况,L,R,RL.
发表于 2023-09-23 02:14:33 回复(0)
我按情况讨论的 竟然过了 我哈哈哈 还是模拟法好做
发表于 2023-01-15 14:36:06 回复(0)

//模拟题
class Solution {
public:     
void replace (string& s,int start,int len,char c){
    for (int i=0;i<len;++i){
        s[i+start]=c;
    }
}

    string solve(string s) {
       char state='.';
    int start=0 ;
    for (int i=0;i<s.length();++i){
        if (s[i]=='L' && state=='.')
        {
            replace(s,start,i-start,'L');
            
            
            start = i+1;
            state='.';
        }
        else if (s[i]=='R' && state=='.'){
            state='R',start=i;
        }
        else if (s[i]=='R' && state=='R'){
            replace(s,start,i-start,'R');
            start=i;
        }
        else if (s[i]=='L' && state=='R'){
            replace(s,start+1,(i-start-1)/2,'R');
//            if (start+)
            replace(s,i-(i-start-1)/2,(i-start-1)/2,'L');
            start = i+1;state='.';
        }
//        else continue;

    }
//    cout<<state;
    if (state=='R'){
        replace (s,start,s.length()-start,'R');
    }
    return s;
    }
};
发表于 2022-02-10 20:23:10 回复(0)
本地编译器可以通过,牛客不行,求大佬指点。
function solve( s ) {
  s = s.split("");
  let le = [];
  let ri = [];
  for(let i = 0; i < s.length; i++) {
      if(s[i] == 'L') le.push(i);
      if(s[i] == 'R') ri.push(i);
  }
 
  let cur = []
  while(le.length || ri.length) {
      for(let i in le) {
          le[i]--;
          if(le[i]<0) {le.splice(i,1); continue;}
          if(s[le[i]] == 'R') {le.splice(i,1); continue}
          s[le[i]] = 'L';
          cur.push(le[i]);
      }
      for(let i in ri) {
          ri[i]++;
          if(ri[i]>s.length-1) {ri.splice(i,1); continue;}
          if(s[ri[i]] == 'L') {
              if(cur.indexOf(ri[i]) === -1) {
                  ri.splice(i,1); continue;
              } else{
                  s[ri[i]] = '.';
                  ri.splice(i,1);
                  let w = le.indexOf(ri[i]);
                  le.splice(w,1);
                  continue;
              }
          }
          s[ri[i]] = 'R';
      }
      cur = [];
  }
  return s.join('');
}

发表于 2021-07-12 20:07:17 回复(0)
这个代码有啥问题么?我检查了很久也没看出毛病😂,本地测和自测的样例都是正确的,但是提交一个样例都没过,麻烦各位大佬帮忙看看哪里有问题呀?交流交流

/**
 * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
 *
 * 
 * @param s string字符串 
 * @return string字符串
 */

function solve( s ) {
  // write code here
  let i = 0, j = 0;
  
  while (s[i] !== 'L') {
      i++;
  }
  while (s[j] !== 'R') {
      j++;
  }

  let i_i = i;
  let j_j = j;
  i --;
  j ++;
  let L_tmp = ''
  let R_tmp = ''
  if (i_i < j_j) {
      while (i >= 0 || j < s.length) {
          if (i >= 0) {
              L_tmp += 'L'
              i--;
          }
          if (j < s.length) {
              R_tmp += 'R'
              j ++;
          }
      }
      return L_tmp + s.slice(i_i, j_j + 1) + R_tmp
  }
  
  if (i_i > j_j) {
      while (i > j  && (i >= 0 || j < s.length)) {
          if (i >= 0) {
              L_tmp += 'L'
              i--;
          }
          if (j < s.length) {
              R_tmp += 'R'
              j ++;
          }
      }
      if (i < j) {
          return s.slice(0, j_j + 1) + R_tmp + L_tmp + s.slice(i_i);
      } 
      return s.slice(0, j_j + 1) + R_tmp + '.' + L_tmp + s.slice(i_i);
  }
}

module.exports = {
    solve : solve
};

发表于 2021-07-03 02:55:02 回复(0)