1. LeetCode第1221题.分割平衡字符串
问题
在一个 平衡字符串 中,‘L’ 和 ‘R’ 字符的数量是相同的。
给你一个平衡字符串 s,请你将它分割成尽可能多的平衡字符串。
注意:分割得到的每个字符串都必须是平衡字符串。
返回可以通过分割得到的平衡字符串的 最大数量 。
示例:
输入:s = “RLRRLLRLRL”
输出:4
解释:s 可以分割为 “RL”、“RRLL”、“RL”、“RL” ,每个子字符串中都包含相同数量的 ‘L’ 和 ‘R’ 。
1)逻辑判断
按照逻辑来看,平衡字符串R和L的数量是相等的,因此首先构造一个判断平衡字符串的函数;
从前往后读取字符串,若当前读取的字符串是平衡字符串,结果+1,并且将当前字符串设置为0,从当前位开始重新读取2个字符;若当前的字符串不是平衡字符串,则顺序的增加一个字符,直到读取完字符串中所有的字符。
自己写的基于逻辑的python程序:
class Solution:
def balancedStringSplit(self, s: str) -> int:
def tt(s):
t = 0
res_R = [t + 1 for i in s if i == 'R']
n_R = len(res_R)
t=0
res_L = [t + 1 for i in s if i == 'L']
n_L = len(res_L)
if n_R == n_L:
return 1
return 0
num = 0
i = 2
currt = s[:i]
while i <= len(s):
if tt(currt):
num +=1
t = 2
currt = s[i:i+t]
else:
t = 1
currt = currt + s[i:i+t]
i = i+t
return num
结果:
2)贪心算法
根据题意,对于一个平衡字符串 ss,若 ss 能从中间某处分割成左右两个子串,若其中一个是平衡字符串,则另一个的 \texttt{L}L 和 \texttt{R}R 字符的数量必然是相同的,所以也一定是平衡字符串。
为了最大化分割数量,我们可以不断循环,每次从 ss 中分割出一个最短的平衡前缀,由于剩余部分也是平衡字符串,我们可以将其当作 ss 继续分割,直至 ss 为空时,结束循环。
代码实现中,可以在遍历 ss 时用一个变量 dd 维护 \texttt{L}L 和 \texttt{R}R 字符的数量之差,当 d=0d=0 时就说明找到了一个平衡字符串,将答案加一。
官方python程序:
class Solution:
def balancedStringSplit(self, s: str) -> int:
ans, d = 0, 0
for ch in s:
if ch == 'L':
d += 1
else:
d -= 1
if d == 0:
ans += 1
return ans
贪心算法程序用时:
通过对比发现,贪心算法的用时却是要少很多,时间复杂度为O(n)
.
2. 贪心算法相关介绍
转载自:
什么是贪心算法
贪心算法是指,在对问题求解时,总是做出在当前看来是最好的选择。
也就是说,不从整体最优上加以考虑,它所做出的仅仅是在某种意义上的局部最优解。
贪心算法没有固定的算法框架,算法设计的关键是贪心策略的选择。
必须注意的是,贪心算法不是对所有问题都能得到整体最优解,选择的贪心策略必须具备无后效性(即某个状态以后的过程不会影响以前的状态,只与当前状态有关。)
贪心策略适用的前提是:局部最优策略能导致产生全局最优解。
实际上,贪心算法适用的情况很少。一般对一个问题分析是否适用于贪心算法,可以先选择该问题下的几个实际数据进行分析,就可以做出判断。
求解思路
- 建立数学模型来描述问题
- 把求解的问题分成若干个子问题
- 对每个子问题求解,得到子问题的局部最优解
- 把子问题的解局部最优解合成原来问题的一个解
存在的问题
- 不能保证求得的最后解是最佳的
- 不能用来求最大值或最小值的问题
- 只能求满足某些约束条件的可行解的范围
实现框架
从问题的某一初始解出发:s
while (朝给定总目标前进一步)
{
利用可行的决策,求出可行解的一个解元素。
}
由所有解元素组合成问题的一个可行解;