力扣每日一题 838. 推多米诺
这道题是看的题解做出来了,因为博主太菜了,做不来。详细题解可以去看官方题解或者灵神题解。本篇博客只是作为一个知识记录。
题目:
n
张多米诺骨牌排成一行,将每张多米诺骨牌垂直竖立。在开始时,同时把一些多米诺骨牌向左或向右推。
每过一秒,倒向左边的多米诺骨牌会推动其左侧相邻的多米诺骨牌。同样地,倒向右边的多米诺骨牌也会推动竖立在其右侧的相邻多米诺骨牌。
如果一张垂直竖立的多米诺骨牌的两侧同时有多米诺骨牌倒下时,由于受力平衡, 该骨牌仍然保持不变。
就这个问题而言,我们会认为一张正在倒下的多米诺骨牌不会对其它正在倒下或已经倒下的多米诺骨牌施加额外的力。
给你一个字符串 dominoes
表示这一行多米诺骨牌的初始状态,其中:
dominoes[i] = 'L'
,表示第i
张多米诺骨牌被推向左侧,dominoes[i] = 'R'
,表示第i
张多米诺骨牌被推向右侧,dominoes[i] = '.'
,表示没有推动第i
张多米诺骨牌。
返回表示最终状态的字符串。
整个字符串无非四种情况:
1)L.....R,这种情况下,字符串不会发生改变
2)L.....L,这种情况下,全部变成向左
3)R.....R,这种情况下,全部变成向右
4)R.....L ,这种情况下,前一半变成右,后一半变成左
具体思路:
我们在原字符串的基础上添加一个首和尾“L”,“R”,这样就可以减少对边界情况的考虑。然后遍历整个新的字符串。在用一个变量,记录先前遇到的第一个“L”或者“R”
①如果遇到“.”,直接跳过就行
②如果在遍历过程中遇到的s[i]和是s[pre]中了,是不是就说明,满足上面的基本情况中的3和2.然后把对应的全部填充成和s[i]一样的就可以了。
③不中的话,就是另外的情况,其实我们只需要判断第四种情况,因为第1中情况不会发生什么变化:首先明确总的填充范围是 :pre + 1 到 i- 1,因为pre和i位置上的是确定的 不用你修改
当pre和i之间的个数为偶数时,首先明确R的填充范围,就是前一半,即pre + 1 ~ (i - (pre+1))/2+1,然后明确L的填充范围,就是后一半,即(i - (pre+1))/2+2)~ i - 1;
当pre和i之间的个数为奇数时,首先明确R的填充范围,就是前一半,即pre + 1 ~ (i - 1)/2; 然后明确L的填充范围,就是后一半,即(i - 1)/2 + 2 ~i - 1;
其实可以一种方式直接判断奇偶性:
前一半为:pre + 1 ~ (pre + i -1)/2
后一半为:(pre + i)/2 + 1 ~ i - 1;
实现:
C++:
class Solution {
public:string pushDominoes(string dominoes) {string s = "L" + dominoes + "R";int n = s.size();int pre = 0;for(int i = 1;i<n;i++){if(s[i]=='.'){continue;}else{if(s[i]==s[pre]){fill(s.begin() + pre + 1,s.begin() + i,s[i]);}else if(s[i]=='L'){fill(s.begin() + pre + 1,s.begin() + (pre + i + 1)/2,'R' );fill(s.begin() + (pre + i)/2 + 1,s.begin() + i ,'L');}pre = i;}}return s.substr(1,n-2);}
};
C#:
public class Solution {public string PushDominoes(string dominoes) {//因为在C#中是不能直接修改字符串的 所以只能曲线救国了char[] s = ("L" + dominoes + "R").ToCharArray();//获取新的拼接好的字符串int size = s.Length;int pre = 0;for(int i = 1; i < size; i++) {if (s[i] == '.') {continue;} else {if (s[i] == s[pre]) {//L...L//R...RArray.Fill(s, s[i],pre + 1,i - pre - 1);} else if (s[i]=='L') {//R...LArray.Fill(s, 'L', (pre + i) / 2 + 1, i - ((pre + i) / 2 + 1));Array.Fill(s, 'R', pre + 1, (pre + i - 1) / 2 - pre);}}//即时更新pre = i;}//重新返回字符串return new string(s, 1, size - 2);}}