leetcode
leetcode 2351 ~ 2400
构造最长的新字符串

构造最长的新字符串

难度:

标签:

题目描述

You are given three integers x, y, and z.

You have x strings equal to "AA", y strings equal to "BB", and z strings equal to "AB". You want to choose some (possibly all or none) of these strings and concatenate them in some order to form a new string. This new string must not contain "AAA" or "BBB" as a substring.

Return the maximum possible length of the new string.

A substring is a contiguous non-empty sequence of characters within a string.

 

Example 1:

Input: x = 2, y = 5, z = 1
Output: 12
Explanation: We can concactenate the strings "BB", "AA", "BB", "AA", "BB", and "AB" in that order. Then, our new string is "BBAABBAABBAB". 
That string has length 12, and we can show that it is impossible to construct a string of longer length.

Example 2:

Input: x = 3, y = 2, z = 2
Output: 14
Explanation: We can concactenate the strings "AB", "AB", "AA", "BB", "AA", "BB", and "AA" in that order. Then, our new string is "ABABAABBAABBAA". 
That string has length 14, and we can show that it is impossible to construct a string of longer length.

 

Constraints:

  • 1 <= x, y, z <= 50

代码结果

运行时间: 29 ms, 内存: 16.0 MB


/*
 * 思路:
 * 使用Java Stream API来实现同样的贪心算法。这里主要是通过Stream来简化循环逻辑。
 */
import java.util.stream.Stream;

public class Solution {
    public int getMaxLength(int x, int y, int z) {
        int[] counts = {x, y, z};
        return Stream.generate(() -> {
            int maxIndex = -1;
            int maxCount = -1;
            for (int i = 0; i < 3; i++) {
                if (counts[i] > maxCount) {
                    maxCount = counts[i];
                    maxIndex = i;
                }
            }
            if (maxIndex == -1) return 0;
            counts[maxIndex] -= 2;
            return 2;
        })
        .limit((x + y + z) / 2)
        .mapToInt(Integer::intValue)
        .sum();
    }
}

解释

方法:

这个题解首先利用了贪心策略来最大化生成字符串的长度。主要思路是:1. 尽可能多地使用'AB'字符串,因为它可以在不违背规则的情况下插入在'AA'和'BB'之间。2. 当'AB'用尽后,根据'AA'和'BB'的数量,交替放置'AA'和'BB'直到其中一种用完。3. 如果'AA'和'BB'数量不相等,那么在数量较多的那种字符后再添加一个相同的字符,但不能超过两个连续的相同字符。计算方法中,min(x, y) * 2计算了可以安全交替放置的'AA'和'BB'的总数量,(x != y)用于检查'AA'和'BB'的数量是否不相同,如果不相同,那么可以额外再放置一个字符,z * 2计算了可以由'AB'提供的字符数。

时间复杂度:

O(1)

空间复杂度:

O(1)

代码细节讲解

🦆
题解中提到尽可能多地使用'AB'字符串,但如何确保在使用'AB'后,剩余的'AA'和'BB'仍能有效交替放置以避免'AAA'或'BBB'?
在使用'AB'字符串后,可以通过交替放置'AA'和'BB'来避免形成'AAA'或'BBB'。例如,如果你有剩余的'AA'和'BB',可以按照'AA-BB-AA-BB'的顺序排列。如果'AB'用尽后仍有剩余的'AA'或'BB',可以确保不会连续使用超过两个相同的字符串块,如使用'AA'后,必须尝试插入'BB'(如果还有剩余),以此保证不会违反规则。
🦆
题解计算最终长度时,将`(x != y)`作为一个条件增加一个字符长度。这个逻辑在所有情况下都是正确的吗,例如如果x或y是0怎么办?
逻辑`(x != y)`用来增加一个字符长度的处理不一定在所有情况下都正确。特别是如果其中一个值(x或y)为0时,就不能再添加任何额外的'AA'或'BB',因为这将导致形成'AAA'或'BBB'。因此,应该在两者都大于0的情况下才考虑增加一个字符,以确保可以安全地添加而不违反连续性规则。
🦆
题解中的`(min(x, y) * 2 + (x != y) + z) * 2`公式计算的结果为什么要乘以2?这是否意味着每个计数单位实际上代表了两个字符?
是的,公式中的乘以2是因为每个字符串单元('AA', 'BB', 'AB')都包含两个字符。因此,不论是'AA', 'BB'还是'AB',每次计数实际上都代表了两个字符。这就是为什么最终结果需要乘以2,以确保返回的是字符的总数而非字符串块的数量。

相关问题