leetcode838.推多米诺

题目大意

一行中有 N 张多米诺骨牌,我们将每张多米诺骨牌垂直竖立。

在开始时,我们同时把一些多米诺骨牌向左或向右推。

在这里插入图片描述
每过一秒,倒向左边的多米诺骨牌会推动其左侧相邻的多米诺骨牌。

同样地,倒向右边的多米诺骨牌也会推动竖立在其右侧的相邻多米诺骨牌。

如果同时有多米诺骨牌落在一张垂直竖立的多米诺骨牌的两边,由于受力平衡, 该骨牌仍然保持不变。

就这个问题而言,我们会认为正在下降的多米诺骨牌不会对其它正在下降或已经下降的多米诺骨牌施加额外的力。

给定表示初始状态的字符串 “S” 。如果第 i 张多米诺骨牌被推向左边,则 S[i] = ‘L’;如果第 i 张多米诺骨牌被推向右边,则 S[i] = ‘R’;如果第 i 张多米诺骨牌没有被推动,则 S[i] = ‘.’。

返回表示最终状态的字符串。

示例 1

输入:".L.R...LR..L.."
输出:"LL.RR.LLRRLL.."

示例 2

输入:"RR.L"
输出:"RR.L"
说明:第一张多米诺骨牌没有给第二张施加额外的力。

解题思路

在某个区间left~right(区间端点均不为".",且除两个端点内,其余元素都是".")内,共有三种情况:

  • 左右端点字符相同:则整个区间倒向一侧;
  • 左端点向右倒,右端点向左倒:这种情况从两端向中间移动,左指针经过的位置变成’R’,右指针经过的位置变成’L’;
  • 左端点向左倒,右端点向右倒:这种情况下,中间字符不发生改变;

首先在字符串左右两端添加额外的字符,左边添加‘L’,右边添加‘R’。记当前字符为’L’,当前位置为0.遍历字符串,找到第1个不是"."的元素,变换该区间内的字符;变换结束后更新当前字符和当前位置;

返回字符串即可;

class Solution {
public:
    string pushDominoes(string dominoes) {
    	if (dominoes.size() < 2)
    		return dominoes;

    	string newStr = "L" + dominoes + "R";
    	// 需要进行更新的区间的左端点信息
    	int left = 0;
    	char L = 'L';

    	for (int i = 1; i < newStr.size(); ++i){
    		// 对当前区间进行更新
    		if (newStr[i] != '.'){
    			cutString(newStr, L, newStr[i], left, i);
    			L = newStr[i];
    			left = i;
    		}
    	}
    	return newStr.substr(1, newStr.size() - 2);
    }

    void cutString(string & dominoes, char L, char R, int left, int right){
    	// 两端的多米诺倒向一侧
    	if (L == R){
    		for (int i = left; i <= right; ++i)
    			dominoes[i] = L;
    	}
    	// 左边向左倒,右边向右倒,则中间多米诺不动
    	else if (L == 'L'){
    		return;
    	}
    	else if (L == 'R'){
    		while (left < right){
    			dominoes[left++] = L;
    			dominoes[right--] = R;
    		}
    	}
    	return ;
    }
};

猜你喜欢

转载自blog.csdn.net/qq_41092190/article/details/106946266
今日推荐