题目:2434. 使用机器人打印字典序最小的字符串
思路:贪心+栈,时间复杂度0(n)。
字符串t其实就是栈,后进先出。要让p的字典序最小,那当然是t每次弹出的字符,都小于或等于“剩下未入t里的字符串的字符”,细节看注释。
C++版本:
class Solution {
public:
string robotWithString(string s) {
int n=s.size();
//预处理出后半段的最小字符
vector<char> v(n+1);
v[n]='z';
for(int i=n-1;i>=0;i--){
v[i]=min(v[i+1],s[i]);
}
// 答案
string t="";
// 栈,模拟t
stack<char> st;
// 遍历字符串s
for(int i=0;i<n;i++){
// 当前字符入栈
st.push(s[i]);
// 当栈不为空,且栈顶字符<=后半段字符串s[i+1,n)中的所有字符
while(st.size()>0 && st.top()<=v[i+1]){
// 出栈
t.push_back(st.top());
st.pop();
}
}
return t;
}
};
JAVA版本:
class Solution {
public String robotWithString(String s) {
int n=s.length();
char[] v=new char[n+1];
v[n]='z';
for(int i=n-1;i>=0;i--){
v[i]=(char)Math.min(v[i+1],s.charAt(i));
}
StringBuilder ans=new StringBuilder();
Deque<Character> st=new ArrayDeque<>();
for(int i=0;i<n;i++){
st.push(s.charAt(i));
while(!st.isEmpty() && st.peek()<=v[i+1]){
ans.append(st.pop());
}
}
return ans.toString();
}
}
Go版本:
func robotWithString(s string) string {
n:=len(s)
v:=make([]byte,n+1)
v[n]=byte('z')
for i:=n-1;i>=0;i-- {
v[i]=min(v[i+1],s[i]);
}
ans:=make([]byte,0,n)
st:=make([]byte,n)
top:=-1
for i:=0;i<n;i++ {
top++
st[top]=s[i]
for top>=0 && st[top]<=v[i+1] {
ans=append(ans,st[top])
top--
}
}
return string(ans)
}