本文转载自微信公众号「程序员小熊」,作者Dine 。转载本文请联系程序员小熊公众号。
前言
大家好,我是来自于华为的程序员小熊。今天给大家带来一道字符串相关的题目,这道题也是今天的力扣每日一题,同时也是华为、苹果、谷歌和雅虎等大厂的面试题,即力扣上的第1221题-分割平衡字符串。
本文主要介绍贪心+栈的策略来解答此题,供大家参考,希望对大家有所帮助。
分割平衡字符串
在一个平衡字符串中,'L' 和 'R' 字符的数量是相同的。
给你一个平衡字符串 s,请你将它分割成尽可能多的平衡字符串。
注意:分割得到的每个字符串都必须是平衡字符串。
返回可以通过分割得到的平衡字符串的最大数量 。
示例
示例及提示
解题思路
要求分割得到平衡字符串的最大数量,很容易想到暴力法,只要遍历一遍字符串,统计字符 'L' 和 'R' 的数量,即可计算出题目要求的结果。
方法一:暴力法
遍历字符串,统计 'L' 和 'R' 的数量,当其数量相同时,则表明可以当前遍历到的字符可跟之前的遍历的那些字符构成平衡字符串,此时统计平衡字符串的个数,并将 'L' 和 'R' 的数量全部置 0,然后继续遍历并统计平衡字符串的个数,直至遍历完整个字符串即可。
Show me the Code
「C」
- int balancedStringSplit(char * s) {
- int numR = 0, numL = 0, res = 0;
- for (int i = 0; s[i] != '\0'; ++i) {
- if (s[i] == 'L') {
- numL++;
- } else {
- numR++;
- }
- if (numL == numR) {
- res++;
- numL = 0;
- numR = 0;
- }
- }
- return res;
- }
复杂度分析
时间复杂度:O(n),其中 n 为字符串的长度,需要遍历一遍字符串。
空间复杂度:O(1),未开辟额外的存储空间。
方法二:贪心 + 栈
本题也可以采用贪心的思想,遍历字符串时,遇到一个个平衡字符串时,将其分割出来,再继续遍历剩余的子字符串。
同时可以采用栈的思想,在遍历字符串时,如果遇到字符 'R' 时,让其入栈,栈内的字符个数加一;遇到字符 'L' 时,让字符 'R' 出栈,栈内的字符个数减一。
遍历的同时判断栈中的字符个数是否为 0,若为 0,则代表已遍历的字符已构成平衡字符串,统计平衡字符串的个数,直至遍历结束。
举例
以字符串 s = "RLLLRRLR" 为例。
例子
在遍历到 s 的某一字符时,用两个变量 cnt 和 res 分别记录字符 'R' 和 'L' 之差以及平衡字符串的数量;
设置两个变量,边遍历边统计平衡字符串个数
计算 cnt 和 res 的大小;
遍历到 'R' 时,cnt 加 1
遍历到 'L'时,cnt 减 1 并计算 res
完整的计算过程,如下动图示:
计算平衡字符串的完整过程动图
Show me the Code
「C」
- int balancedStringSplit(char * s) {
- int cnt = 0, res = 0;
- for (int i = 0; s[i] != '\0'; ++i) {
- cnt += s[i] == 'R' ? 1 : -1;
- if (cnt == 0) {
- res++;
- }
- }
- return res;
- }
「C++」
- int balancedStringSplit(string s) {
- int res = 0, cnt = 0;
- for (auto a : s) {
- cnt += a == 'R' ? 1 : -1;
- if (cnt == 0) {
- res += 1;
- }
- }
- return res;
- }
「Java」
- int balancedStringSplit(String s) {
- int res = 0, cnt = 0;
- for (int i = 0; i < s.length(); i++) {
- cnt += s.charAt(i) == 'R' ? 1 : -1;
- if (cnt == 0) {
- res += 1;
- }
- }
- return res;
- }
「Python3」
- def balancedStringSplit(self, s: str) -> int:
- res, cnt = 0, 0
- for c in s:
- cnt += 1 if c == 'R' else -1
- if cnt == 0:
- res += 1
- return res
「Golang」
- func balancedStringSplit(s string) int {
- cnt, res := 0, 0
- for _, ch := range s {
- if ch == 'R' {
- cnt++
- } else {
- cnt--
- }
- if cnt == 0 {
- res++
- }
- }
- return res
- }
复杂度分析
- 时间复杂度:O(n),其中 n 为字符串的长度,需要遍历一遍字符串。
- 空间复杂度:O(1),未开辟额外的存储空间。