Given a string p consisting only of the characters 'I' and 'D', construct the smallest number that follows the given pattern using digits from 1 to 9, where each digit is used at most once.
- 'I' indicates that the next digit should be greater than the current digit.
- 'D' indicates that the next digit should be smaller than the current digit.
Return the smallest number that satisfies the entire pattern.
Examples:Â
Input: p = "D"
Output: "21"
Explanation: 'D' represents decreasing order, so the first digit must be greater than the second digit. Among all possible numbers like 21, 31, 54, and 87, the smallest valid number is 21.Input: p = "IIDDD"
Output: "126543"
Explanation: The smallest number satisfying the pattern is: 1 < 2 < 6 > 5 > 4 > 3, which follows the pattern: I - I - D - D - D
Table of Content
[Naive Approach] Backtracking - O(9!) Time and O(n) Space
The idea is to use backtracking to generate all possible numbers that satisfy the given pattern and keep track of the smallest valid number.
We construct the number one digit at a time. For every position, we choose an unused digit that satisfies the current pattern condition.
- If the current character is 'I', the next digit must be greater than the previous digit.
- If the current character is 'D', the next digit must be smaller than the previous digit.
- For the first position, any digit from 1 to 9 can be chosen.
- A visited array is used to ensure that every digit is used at most once.
#include <bits/stdc++.h>
using namespace std;
string res = "987654321";
void solve(vector<int>& vis, string& p, int i, string& ans)
{
if (i == p.length()) {
if (res > ans)
res = ans;
return;
}
// Choose the first digit.
if (i == -1) {
for (int j = 1; j <= 9; j++) {
if (vis[j] == 0) {
vis[j] = 1;
ans += j + '0';
solve(vis, p, i + 1, ans);
ans.pop_back();
vis[j] = 0;
}
}
}
else {
int t = ans[ans.length() - 1] - '0';
if (p[i] == 'D') {
// Choose an unused smaller digit.
for (int j = t - 1; j >= 1; j--) {
if (vis[j] == 0) {
vis[j] = 1;
ans += j + '0';
solve(vis, p, i + 1, ans);
ans.pop_back();
vis[j] = 0;
}
}
}
else {
// Choose an unused greater digit.
for (int j = t + 1; j <= 9; j++) {
if (vis[j] == 0) {
vis[j] = 1;
ans += j + '0';
solve(vis, p, i + 1, ans);
ans.pop_back();
vis[j] = 0;
}
}
}
}
}
string minNumber(string &p)
{
string ans = "";
vector<int> vis(10, 0);
solve(vis, p, -1, ans);
return res;
}
int main()
{
string p = "IIDDD";
cout << minNumber(p);
return 0;
}
class GFG {
static String res;
static void solve(int[] vis, String p, int i, StringBuilder ans) {
if (i == p.length()) {
if (res.compareTo(ans.toString()) > 0) {
res = ans.toString();
}
return;
}
// Choose the first digit.
if (i == -1) {
for (int j = 1; j <= 9; j++) {
if (vis[j] == 0) {
vis[j] = 1;
ans.append((char)('0' + j));
solve(vis, p, i + 1, ans);
ans.deleteCharAt(ans.length() - 1);
vis[j] = 0;
}
}
}
else {
int t = ans.charAt(ans.length() - 1) - '0';
if (p.charAt(i) == 'D') {
// Choose an unused smaller digit.
for (int j = t - 1; j >= 1; j--) {
if (vis[j] == 0) {
vis[j] = 1;
ans.append((char)('0' + j));
solve(vis, p, i + 1, ans);
ans.deleteCharAt(ans.length() - 1);
vis[j] = 0;
}
}
}
else {
// Choose an unused greater digit.
for (int j = t + 1; j <= 9; j++) {
if (vis[j] == 0) {
vis[j] = 1;
ans.append((char)('0' + j));
solve(vis, p, i + 1, ans);
ans.deleteCharAt(ans.length() - 1);
vis[j] = 0;
}
}
}
}
}
static String minNumber(String p) {
res = "987654321";
StringBuilder ans = new StringBuilder();
int[] vis = new int[10];
solve(vis, p, -1, ans);
return res;
}
public static void main(String[] args) {
String p = "IIDDD";
System.out.println(minNumber(p));
}
}
def minNumber(p: str) -> str:
n = len(p)
vis = [False] * 10
ans = []
def solve(i):
if i == n + 1:
return True
for j in range(1, 10):
if vis[j]:
continue
if i > 0:
prev = ans[-1]
if p[i - 1] == 'I' and j <= prev:
continue
if p[i - 1] == 'D' and j >= prev:
continue
vis[j] = True
ans.append(j)
if solve(i + 1):
return True
ans.pop()
vis[j] = False
return False
solve(0)
return ''.join(map(str, ans))
if __name__ == "__main__":
p = "IIDDD"
print(minNumber(p))
using System;
class GFG {
static string res = "987654321";
public void solve(int[] vis, string p, int i, string ans) {
if (i == p.Length) {
if (string.Compare(res, ans, StringComparison.Ordinal) > 0) {
res = ans;
}
return;
}
// Choose the first digit.
if (i == -1) {
for (int j = 1; j <= 9; j++) {
if (vis[j] == 0) {
vis[j] = 1;
ans += (char)('0' + j);
solve(vis, p, i + 1, ans);
ans = ans.Substring(0, ans.Length - 1);
vis[j] = 0;
}
}
}
else {
int t = ans[ans.Length - 1] - '0';
if (p[i] == 'D') {
// Choose an unused smaller digit.
for (int j = t - 1; j >= 1; j--) {
if (vis[j] == 0) {
vis[j] = 1;
ans += (char)('0' + j);
solve(vis, p, i + 1, ans);
ans = ans.Substring(0, ans.Length - 1);
vis[j] = 0;
}
}
}
else {
// Choose an unused greater digit.
for (int j = t + 1; j <= 9; j++) {
if (vis[j] == 0) {
vis[j] = 1;
ans += (char)('0' + j);
solve(vis, p, i + 1, ans);
ans = ans.Substring(0, ans.Length - 1);
vis[j] = 0;
}
}
}
}
}
public string minNumber(string p) {
res = "987654321";
string ans = "";
int[] vis = new int[10];
solve(vis, p, -1, ans);
return res;
}
public static void Main() {
string p = "IIDDD";
GFG obj = new GFG();
Console.WriteLine(obj.minNumber(p));
}
}
function solve(vis, p, i, ans, res)
{
if (i === p.length) {
if (res.value > ans)
res.value = ans;
return;
}
// Choose the first digit.
if (i === -1) {
for (let j = 1; j <= 9; j++) {
if (vis[j] === 0) {
vis[j] = 1;
ans += String(j);
solve(vis, p, i + 1, ans, res);
ans = ans.slice(0, -1);
vis[j] = 0;
}
}
}
else {
let t = Number(ans[ans.length - 1]);
if (p[i] === "D") {
// Choose an unused smaller digit.
for (let j = t - 1; j >= 1; j--) {
if (vis[j] === 0) {
vis[j] = 1;
ans += String(j);
solve(vis, p, i + 1, ans, res);
ans = ans.slice(0, -1);
vis[j] = 0;
}
}
}
else {
// Choose an unused greater digit.
for (let j = t + 1; j <= 9; j++) {
if (vis[j] === 0) {
vis[j] = 1;
ans += String(j);
solve(vis, p, i + 1, ans, res);
ans = ans.slice(0, -1);
vis[j] = 0;
}
}
}
}
}
function minNumber(p)
{
let ans = "";
let vis = new Array(10).fill(0);
let res = {value : "987654321"};
solve(vis, p, -1, ans, res);
return res.value;
}
// Driver code
let p = "IIDDD";
console.log(minNumber(p));
Output
126543
[Expected Approach-1] Using Stack - O(n) Time and O(n) Space
The idea is to start with the smallest possible digit and use a stack to arrange the digits according to the pattern.
For a pattern of length n, the answer contains n + 1 digits. We consider the digits from 1 to n + 1.
The important observation is:
- For 'I', the next digit must be greater than the current digit. So, push the current digit into the stack and pop all elements. This places the digits in increasing order.
- For 'D', the next digit must be smaller than the current digit. So, keep pushing the digits into the stack. When an 'I' is encountered or the pattern ends, pop all elements. Due to the LIFO property of the stack, the digits come out in decreasing order.
#include <bits/stdc++.h>
using namespace std;
string minNumber(string &p) {
stack<int> st;
string ans;
for (int i = 0; i <= p.length(); i++) {
st.push(i + 1);
// Flush the stack whenever an increasing relation is found
if (i == p.length() || p[i] == 'I') {
while (!st.empty()) {
ans += to_string(st.top());
st.pop();
}
}
}
return ans;
}
int main() {
string p = "IIDDD";
cout << minNumber(p) << endl;
return 0;
}
import java.util.Stack;
class GFG {
static String minNumber(String p) {
Stack<Integer> st = new Stack<>();
String ans = "";
for (int i = 0; i <= p.length(); i++) {
st.push(i + 1);
// Flush the stack whenever an increasing relation is found
if (i == p.length() || p.charAt(i) == 'I') {
while (!st.isEmpty()) {
ans += st.pop();
}
}
}
return ans;
}
public static void main(String[] args) {
String p = "IIDDD";
System.out.println(minNumber(p));
}
}
def minNumber(p: str) -> str:
st = []
ans = ""
for i in range(len(p) + 1):
st.append(i + 1)
# Flush the stack whenever an increasing relation is found
if i == len(p) or p[i] == 'I':
while st:
ans += str(st.pop())
return ans
if __name__ == "__main__":
p = "IIDDD"
print(minNumber(p))
using System;
using System.Collections.Generic;
class GFG {
public string minNumber(string p) {
Stack<int> st = new Stack<int>();
string ans = "";
for (int i = 0; i <= p.Length; i++) {
st.Push(i + 1);
// Flush the stack whenever an increasing relation is found
if (i == p.Length || p[i] == 'I') {
while (st.Count > 0) {
ans += st.Pop();
}
}
}
return ans;
}
public static void Main() {
string p = "IIDDD";
GFG obj = new GFG();
Console.WriteLine(obj.minNumber(p));
}
}
function minNumber(p)
{
let st = [];
let ans = "";
for (let i = 0; i <= p.length; i++) {
st.push(i + 1);
// Flush the stack whenever an increasing relation
// is found
if (i == p.length || p[i] == "I") {
while (st.length > 0) {
ans += st.pop();
}
}
}
return ans;
}
// Driver code
let p = "IIDDD";
console.log(minNumber(p));
Output
126543
[Expected Approach-2] Directly Reverse Consecutive D Sequences - O(n) Time and O(n) Space
The idea is to start with the digits from 1 to n + 1 in increasing order. Whenever we find a consecutive sequence of 'D' characters, we reverse the corresponding digits.
- Create an array containing the digits from 1 to n + 1.
- Traverse the pattern and find each consecutive sequence of 'D'.
- If a sequence starts at index i and continues until j - 1, reverse the digits from index i to j.
- Return the resulting digits.
Consider p = "IIDDD".
- Initially, the digits are: 1 2 3 4 5 6
- The first two characters are 'I', so their digits remain unchanged.
- The last three characters are 'DDD'. Therefore, reverse the corresponding digits: 1 2 [3 4 5 6]
- After reversal: 1 2 6 5 4 3
Hence, the smallest number is 126543.
#include <bits/stdc++.h>
using namespace std;
string minNumber(string &p) {
int n = p.length();
string ans = "";
// Start with digits from 1 to n + 1.
for (int i = 1; i <= n + 1; i++) {
ans += char('0' + i);
}
// Reverse every consecutive sequence of D.
for (int i = 0; i < n; i++) {
if (p[i] == 'D') {
int j = i;
while (j < n && p[j] == 'D') {
j++;
}
reverse(ans.begin() + i, ans.begin() + j + 1);
i = j - 1;
}
}
return ans;
}
int main() {
string p = "IIDDD";
cout << minNumber(p) << endl;
return 0;
}
class GFG {
static String minNumber(String p) {
int n = p.length();
String ans = "";
// Start with digits from 1 to n + 1.
for (int i = 1; i <= n + 1; i++) {
ans += (char)('0' + i);
}
// Reverse every consecutive sequence of D.
for (int i = 0; i < n; i++) {
if (p.charAt(i) == 'D') {
int j = i;
while (j < n && p.charAt(j) == 'D') {
j++;
}
StringBuilder temp = new StringBuilder(ans.substring(i, j + 1));
temp.reverse();
ans = ans.substring(0, i) + temp + ans.substring(j + 1);
i = j - 1;
}
}
return ans;
}
public static void main(String[] args) {
String p = "IIDDD";
System.out.println(minNumber(p));
}
}
def minNumber(p: str) -> str:
n = len(p)
ans = ""
# Start with digits from 1 to n + 1.
for i in range(1, n + 2):
ans += chr(ord('0') + i)
# Reverse every consecutive sequence of D.
ans = list(ans)
i = 0
while i < n:
if p[i] == 'D':
j = i
while j < n and p[j] == 'D':
j += 1
ans[i:j + 1] = reversed(ans[i:j + 1])
i = j
else:
i += 1
return ''.join(ans)
if __name__ == "__main__":
p = "IIDDD"
print(minNumber(p))
using System;
class GFG {
public string minNumber(string p) {
int n = p.Length;
string ans = "";
// Start with digits from 1 to n + 1.
for (int i = 1; i <= n + 1; i++) {
ans += (char)('0' + i);
}
// Reverse every consecutive sequence of D.
char[] temp = ans.ToCharArray();
for (int i = 0; i < n; i++) {
if (p[i] == 'D') {
int j = i;
while (j < n && p[j] == 'D') {
j++;
}
Array.Reverse(temp, i, j - i + 1);
i = j - 1;
}
}
return new string(temp);
}
public static void Main() {
string p = "IIDDD";
GFG obj = new GFG();
Console.WriteLine(obj.minNumber(p));
}
}
function minNumber(p)
{
let n = p.length;
let ans = "";
// Start with digits from 1 to n + 1.
for (let i = 1; i <= n + 1; i++) {
ans += String.fromCharCode("0".charCodeAt(0) + i);
}
// Reverse every consecutive sequence of D.
let temp = ans.split("");
for (let i = 0; i < n; i++) {
if (p[i] == "D") {
let j = i;
while (j < n && p[j] == "D") {
j++;
}
let part = temp.slice(i, j + 1).reverse();
for (let k = 0; k < part.length; k++) {
temp[i + k] = part[k];
}
i = j - 1;
}
}
return temp.join("");
}
// Driver code
let p = "IIDDD";
console.log(minNumber(p));
Output
126543