1.选择第二题进行分析。
给定n位正整数a,去掉其中任意k≤n 个数字后,剩下的数字按原次序排列组成一个新 的正整数。对于给定的n位正整数a和正整数 k,设计一个算法找出剩下数字组成的新数最 小的删数方案。
输入
178543
4
输出132.问题描述:就是删掉指定数字中的一些数字,然后重新组成一个新的数使得这个数达到最小。3.算法描述:这个问题第一眼看下去容易想到对数组不停的排序然后不断删掉最大的,但是按着这个思路去做却发现,不断提取整型数组然后排序会比较复杂,因为要不断求余数等等,而且代码不好写。后来发现使用串数组解决这个问题会比较的容易,而且删除对应的字符可以直接调用str.erase的函数来做,就简单很多。通过做贪心选择,不断地把S【i】>s[i+1]的对应s【i】字符删掉,最后如果要删掉的字符数目比这个过程实际上多出几个,就删掉最后面的几个,就可以了,输出方面要注意将‘0’字符输出注意一下。4.代码如下:
#include<string>
#include<iostream>
using namespace std;
int n;
string s;
int main()
{
cin>>s>>n;
int fin_del=0;
for(int j=0;j<n;j++){
for(int i=0;i<s.size()-1;i++)
{
if(s[i+1]<s[i])
{
s.erase(i,1);
fin_del++;
break;
}
}
}
if(n-fin_del!=0){
s.erase(s.size()-(n-fin_del)+1,s.size());
}
bool F=false;
for(int i=0;i<s.size();i++)
{
if(s[i]!=‘0‘ || i==s.size()-1)
F=true;
if(F)
printf("%c",s[i]);
}
}空间复杂度的话由于是解决问题是在一维数组解决的,所以是O(n);
时间复杂度:为 O(n*(n-1)+n) 即O(n*n) 第一个式子就是比较所用的时间,第二个式子是输出字符用的时间,总的时间复杂度是O(n*n);
心得体会:个人觉得三道实践题中,这道题目是最困难的,因为老想着余数法来把对应数字提取出来再不断排序删除,实际上这里如果能很好的利用字符数字,数字大,ASC2页大的实质,再利用String的erase函数就可以很直接的对数组做出删除。
原文地址:https://www.cnblogs.com/suanfasfather/p/10034215.html