题目描述
给定只含 "I"
(增大)或 "D"
(减小)的字符串 S
,令 N = S.length
。
返回 [0, 1, ..., N]
的任意排列 A
使得对于所有 i = 0, ..., N-1
,都有:
- 如果
S[i] == "I"
,那么A[i] < A[i+1]
- 如果
S[i] == "D"
,那么A[i] > A[i+1]
样例
输出:"IDID"
输出:[0,4,1,3,2]
输出:"III"
输出:[0,1,2,3]
输出:"DDI"
输出:[3,2,0,1]
限制
1 <= S.length <= 1000
S
只包含字符"I"
或"D"
。
算法
(贪心构造) $O(n)$
- 从头开始遍历 S 数组,每次遇到
I
时,填尽可能小的数字;遇到D
时,填尽可能大的数字。最后一个位置填最终剩下的一个数字即可。 - 这么做保证每次都能找到一个合法的数字,如果遇到
I
时,填了一个较大的数字,可能导致后续找不到数字填。
时间复杂度
- 仅扫描一遍数组,故总时间复杂度为 $O(n)$。
C++ 代码
class Solution {
public:
vector<int> diStringMatch(string S) {
int n = S.length();
vector<int> ans(n + 1);
int l = 0, r = n;
for (int i = 0; i < n; i++) {
if (S[i] == 'I')
ans[i] = l++;
else
ans[i] = r--;
}
ans[n] = l;
return ans;
}
};