通过万岁!!!
- 题目:给定一列诺骨牌数组,然后在任何位置都会给一个向左或者向右的力量。数组中L表示向左的力,R表示向右的力,点号表示没有力量的正常骨牌。注意,力会同时给。然后最后输出每个骨牌的方向。
- 思路:就是遍历字符串,如果力量先是向右的,然后向左,则会出现相互依靠的情况,特别是中间可能会有一个站着的,这个返回的时候就直接用点号就可以。需要右一个变量记录开始的位置,这个位置表示我们需要开始改变的地方(begin)。例如begin的地方是点,然后一个向左的力,则从begin到这个向左的力的位置都要变成L。如果begin的地方是R,则遇到左以后需要平分begin到这个R的骨牌。然后我们还需要有一个变量,来记录之前的力量的方向,我们用一个-1表示向左,0表示没有力,1表示向右。要是不太明白,可以看一下伪代码。
- 技巧:
- 我们可以先定义一个char的数组,这样方便修改。
- 这里用到了双指针,就是begin和我们遍历数组的时候的i
伪代码
首先,要是只有数组长度是1,则直接返回本身即可
然后定义数组ans,长度跟字符串的长度一样
接着定义开始改变的下标begin和力的反方向flag,初始化都是1
接下来遍历字符串,迭代下标是i
如果力是向左的
并且之前没有力,也就是flag=0,则直接从begin开始一直到i都改成L即可
如果之前的力是向右的,也就是flag=1,这时候需要将begin到i之间进行对半分,左半边变成R,右半边变成L,注意这时候需要判断中间会不会右一个是点号的
最后修改begin的位置为i
如果力是向右的
这时候需要判断之前的力是不是还有向右的,如果有的话,先让begin到i之间的变成R
这里要修改begin和flag
如果点的时候
这时候判断如果力也是0,那么就将i位置变成点号即可
最后我们看一下,最后一个力是不是向右的,如果是向右的,则将begin到最后的位置都变成R
最后将char数组转成String返回即可
java代码
class Solution {
public String pushDominoes(String dominoes) {
char ans[] = new char[dominoes.length()];
int begin = 0, flag = 0;// flag表示力量,-1表示向左,0表示没有力量,1表示向右
for (int i = 0; i < dominoes.length(); i++) {
if (dominoes.charAt(i) == 'L') {
if (flag == 0)
for (int j = begin; j <= i; j++) {
ans[j] = 'L';
}
if (flag == 1) {
int mid = (i - begin) / 2;
for (int j = 0; j <= mid; j++) {
ans[begin + j] = 'R';
ans[i - j] = 'L';
}
if ((i - begin) % 2 == 0) ans[begin + mid] = '.';// 中间有一个.
flag = 0;// 力量回复
}
begin = i;
} else if (dominoes.charAt(i) == 'R') {
if (flag == 1) {
for (int j = begin; j < i; j++) {
ans[j] = 'R';
}
}
begin = i;
flag = 1;
} else {// 这时候一定是.
if (flag == 0) ans[i] = '.';
}
}
// 还有向右边的力
if (flag == 1) {
for (int i = begin; i < dominoes.length(); i++) {
ans[i] = 'R';
}
}
return new String(ans);
}
}
- 总结:题目不是很难,主要是要想明白几种情况,左拥右抱、向右倒、向左倒。还有之所以用数组,是为了一次行拿到全部的空间,从而不需要动态扩充。