携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第16天,点击查看活动详情
6150. 根据模式串构造最小数字
难度中等13
给你下标从 0 开始、长度为 n 的字符串 pattern ,它包含两种字符,'I' 表示 上升 ,'D' 表示 下降 。
你需要构造一个下标从 0 开始长度为 n + 1 的字符串,且它要满足以下条件:
num包含数字'1'到'9',其中每个数字 至多 使用一次。- 如果
pattern[i] == 'I',那么num[i] < num[i + 1]。 - 如果
pattern[i] == 'D',那么num[i] > num[i + 1]。
请你返回满足上述条件字典序 最小 的字符串 **num。
示例 1:
输入: pattern = "IIIDIDDD"
输出: "123549876"
解释: 下标 0 ,1 ,2 和 4 处,我们需要使 num[i] < num[i+1] 。
下标 3 ,5 ,6 和 7 处,我们需要使 num[i] > num[i+1] 。
一些可能的 num 的值为 "245639871" ,"135749862" 和 "123849765" 。
"123549876" 是满足条件最小的数字。
注意,"123414321" 不是可行解因为数字 '1' 使用次数超过 1 次。
示例 2:
输入: pattern = "DDD"
输出: "4321"
解释:
一些可能的 num 的值为 "9876" ,"7321" 和 "8742" 。
"4321" 是满足条件最小的数字。
提示:
1 <= pattern.length <= 8pattern只包含字符'I'和'D'。
代码1:
class Solution {
public:
string smallestNumber(string pattern) {
string s;
for (int i = 1; i <= pattern.size() + 1; i++) {
s += to_string(i);
}
while (true) {
int flag = 0;
for (int i = 0; i < pattern.size(); i++) {
if (pattern[i] == 'I' && s[i] < s[i + 1]) {
flag = 0;
}
else if (pattern[i] == 'D' && s[i] > s[i + 1]) {
flag = 0;
}
else {flag = 1; break;}
}
if (flag == 0)break;
next_permutation(s.begin(), s.end());
}
return s;
}
};
代码2:
string pattern, ans;
bool used[10], ok;
void dfs(int pos) {
if (pos > pattern.size()) { ok = true; return; }
for (int i = 1; i <= 9; i++) if (!used[i]) {
if (pos > 0) {
int last = ans.back() - '0';
if (pattern[pos - 1] == 'I') {
if (i < last) goto FAILED;
} else {
if (i > last) goto FAILED;
}
}
ans.push_back(i + '0');
used[i] = true;
dfs(pos + 1);
if (ok) return;
used[i] = false;
ans.pop_back();
FAILED: continue;
}
}
public:
string smallestNumber(string pattern) {
this->pattern = pattern;
dfs(0);
return ans;
}
};