返回
942. 增减字符串匹配 - 贪心构造的魅力
后端
2023-09-11 16:42:07
## 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 的两端开始,分别用两个指针 i 和 j 指向数组的第一个元素和最后一个元素。然后,我们将 s_i 和 s_j 分别设置为 1 和 0。接着,我们将 i 和 j 分别向数组的中间移动,并在移动过程中更新 s_i 和 s_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"
希望本篇文章对您有所帮助!如果您有任何问题或建议,请随时提出。