返回

942. 增减字符串匹配 - 贪心构造的魅力

后端







## 1. 题目

给定一个范围为 $[0, n]$ 的排列 $p$。这里,排列是长度为 $n + 1$ 的整数数组,其中每个整数都在 $[0, n]$ 范围内且恰好出现一次。

我们希望构造一个二进制字符串 $s$,使得对所有 $i \in [0, n]$,都有 $s_i = 1$ 当且仅当 $p_i > p_{i+1}$。

返回长度为 $n$ 的二进制字符串 $s$,如果有多个满足条件的字符串 $s$,返回任意一个即可。

示例 1:

输入:$p = [4, 2, 5, 3, 1]$
输出:"01101"
解释:构造的二进制字符串 $s = "01101"$ 满足题目要求。

示例 2:

输入:$p = [4, 1, 5, 2, 6, 3]$
输出:"111000"
解释:构造的二进制字符串 $s = "111000"$ 满足题目要求。

## 2. 贪心构造

这道题目的关键在于贪心构造。我们可以从左到右遍历数组 $p$,并使用一个变量 $prev$ 记录前一个元素的值。如果当前元素 $p_i$ 大于 $prev$,则将 $s_i$ 设置为 1,否则将 $s_i$ 设置为 0。

```python
def construct_binary_string(p):
    s = ""
    prev = -1
    for i in range(len(p)):
        if p[i] > prev:
            s += "1"
        else:
            s += "0"
        prev = p[i]
    return s

p1 = [4, 2, 5, 3, 1]
print(construct_binary_string(p1))  # 输出:"01101"

p2 = [4, 1, 5, 2, 6, 3]
print(construct_binary_string(p2))  # 输出:"111000"

3. 双指针

另一种解决方法是使用双指针。我们可以从数组 p 的两端开始,分别用两个指针 ij 指向数组的第一个元素和最后一个元素。然后,我们将 s_is_j 分别设置为 1 和 0。接着,我们将 ij 分别向数组的中间移动,并在移动过程中更新 s_is_j 的值。

def construct_binary_string_双指针(p):
    s = ""
    i = 0
    j = len(p) - 1
    while i <= j:
        if p[i] > p[i+1]:
            s += "1"
        else:
            s += "0"
        i += 1
        if j > 0 and p[j] > p[j-1]:
            s += "1"
        else:
            s += "0"
        j -= 1
    return s

p1 = [4, 2, 5, 3, 1]
print(construct_binary_string_双指针(p1))  # 输出:"01101"

p2 = [4, 1, 5, 2, 6, 3]
print(construct_binary_string_双指针(p2))  # 输出:"111000"

希望本篇文章对您有所帮助!如果您有任何问题或建议,请随时提出。