1.移掉K位数字
给定一个以字符串表示的非负整数 num,移除这个数中的 k 位数字,使得剩下的数字最小。
题目链接
分析:
char * removeKdigits(char * num, int k){
if(k==0)
return num;
int len=strlen(num);
if(k>=len)
return "0";
char *stack=(char *)calloc(len,sizeof(char));
int top=0;
for(int i=0;i<len;i++)
{
if(top!=0&&num[i]<stack[top-1]&&k)//覆盖
{
stack[top-1]=num[i];
k--;
while(top>1&&stack[top-1]<stack[top-2]&&k)//两个相同的挨着
{
stack[top-2]=stack[top-1];
top--;
k--;
}
}
else//直接填写在后面
stack[top++]=num[i];
}
//已经全部入栈
stack[top-k]='\0';
int sub=0;
while(sub!=top&&stack[sub]=='0')//去除前面所有的0
{
sub++;
}
if(sub==top)//栈内全是0
return "0";
return stack+sub;
}
2.去除重复字母
给你一个字符串 s ,请你去除字符串中重复的字母,使得每个字母只出现一次。需保证 返回结果的字典序最小(要求不能打乱其他字符的相对位置)
题目链接
分析:
char * removeDuplicateLetters(char * s){
int len=strlen(s);
if(len==1)
return s;
int num[26]={0};
for(int i=0;i<len;i++)//统计出现次数
{
num[s[i]-'a']++;
}
int flag[26]={0};//0表示没有入栈
char *stack=(char *)malloc(sizeof(char)*(len+1));
int top=0;
for(int i=0;i<len;i++)
{
if(top!=0&&flag[s[i]-'a']==0&&s[i]<stack[top-1]&&num[stack[top-1]-'a']>1)//栈顶大于来的元素且栈顶元素有重复个数
{
num[stack[top-1]-'a']--;//个数减1
flag[stack[top-1]-'a']=0;//表示栈内没有该元素
flag[s[i]-'a']=1;//表示栈内有了该元素
stack[top-1]=s[i];//覆盖
while(top>1&&stack[top-2]>stack[top-1]&&num[stack[top-2]-'a']>1)//入栈后比前面小且前面的还有
{
num[stack[top-2]-'a']--;//一定要放在上面,否则位置已经换了
flag[stack[top-2]-'a']=0;
stack[top-2]=stack[top-1];
top--;
}
}
else
{
if(flag[s[i]-'a']==0)//目前栈内没有该元素则填入
{
stack[top++]=s[i];//填入
flag[s[i]-'a']=1;
}
else
num[s[i]-'a']--;//不入栈,个数少一个
}
}
stack[top]='\0';
return stack;
}