目录
第一题 -- 字符串中不同整数的数目
题目描述:
简单来说,就是从目标字符串中提取数字串,并统计个数。
注意:①需要去重 ②需要去掉前导零。
我的做法:
① 使用map数组存储是否存在过(可用set、unorderset代替)
② 使用一个bool型判断此串是否为全零
时间复杂度(因为string传入map是通过传值方式,O(m)的参数传递,m为平均数字串长度)
class Solution {
public:
map<string,bool>s; // 负责去重
bool flag=0; // 之前字符是数字的标志
int numDifferentIntegers(string word) {
string tmp="";
flag=0;
for(int i=0;i<word.length();i++){
if(word[i]>='0'&&word[i]<='9'){
if(tmp==""&&word[i]=='0'){
flag=1;
continue;
}
tmp+=word[i];
}
else{
if(tmp!=""){
s[tmp]=1;
}
else if(flag){ // 可能是00000之类的全零数字串
s["0"]=1;
}
flag=0;
tmp="";
}
}
if(tmp!=""){
s[tmp]=1;
}
else if(flag){
s["0"]=1;
}
return (int)s.size();
}
};
第二题 -- 还原排列的最少操作
题目大意:
简单来说,就是通过上述的操作,返回原始顺序需要最少的操作步骤。
我的做法:
直接模拟即可,因为n最大为1000,我直接打表想看看是否有规律,结果哈哈哈直接是答案。算法复杂度.
class Solution {
public:
bool check(vector<int>&p){
for(int i=0;i<p.size();i++){
if(i!=p[i])return false;
}
return true;
}
int reinitializePermutation(int n) {
vector<int>p(n);
for(int i=0;i<n;i++)p[i]=i;
int cnt=0;
do{
vector<int>arr(n);
for(int i=0;i<n;i++){
if(i&1){
arr[i]=p[n/2+(i-1)/2];
}
else{
arr[i]=p[i/2];
}
// cout<<arr[i]<<" ";
}
// cout<<endl;
p=arr;
cnt++;
}while(!check(p));
return cnt;
}
};
第三题 -- 替换字符串中的括号内容
题目大意:
简单来说,就是将(XXX)根据knowledge字典转换为真正的字符串,有点像函数传参。
我的做法:
字典的词数最多为1e5,所有直接遍历算法复杂度为,肯定会超时。但使用map存储,时间复杂度缩小为,符合题目要求。
class Solution {
public:
map<string,int>p;
string evaluate(string s, vector<vector<string>>& knowledge) {
string ans="";
string t;
for(int i=0;i<knowledge.size();i++){
p[knowledge[i][0]]=i+1; // 为节省空间,存储的是序号
}
for(int i=0;i<s.length();i++){
if(s[i]=='('){
i++;
string t="";
while(s[i]!=')'){
t+=s[i++];
}
int j=p[t];
if(j==0)ans+='?'; // 字典中不存在,输出?
else ans+=knowledge[j-1][1];
}
else{
ans+=s[i];
}
}
return ans;
}
};
第四题 -- 好因子的最大数目
题目大意:
简单来说,就是求质因子数不超过primeFactors个的所有数中,其非质因子数目的最大乘积,需要mod 1e9+7.
我的做法:
我们通常知道,一个数的非质因子是由质因子组合相乘而得来的。
举个例子:一个数存在x个为2的质因子,y个为3的质因子,z个为5的质因子,那么此数不同非质因子的个数为 x*y*z。
如果理解了上面那个例子,那么这道题就转换为:
我们通过举例:
n=2时,ans=2。 n=3时,ans=3。 n=4时,ans=2*2=4。
n=5时,ans=3*2=6 n=6时,ans=3*3=9(>2*2*2) n=7时,ans=3*2*2=12
我们可以以此类推,可以发现,可以推出规律:ans(n)=ans(n-3)*3。
为什么得出这样的结论?
因为其他质因子,例如5<3*2,7<3*2*2,11<3*3*3*2,而且可以发现,随着其他质因子的增大,差距愈发明显。而2这个质因子,当n=6时,2*2*2 < 3*3,故除了n=4,首选3必然会有更大的结果。
算法复杂度。
const int mod = 1e9+7;
typedef long long ll;
class Solution {
public:
ll mod_pow(ll a,ll b){ // 快速幂,函数作用为求 a^b
ll r = 1;
while(b){
if(b&1)r=(r*a)%mod;
a=(a*a)%mod;
b>>=1;
}
return r%mod;
}
int maxNiceDivisors(int primeFactors) {
if(primeFactors<=4)return primeFactors;
ll p = 1;
for(int i=2;i<=4;i++){ // 判断是由哪个子集通过增加3得来的
if((primeFactors-i)%3==0){
int t = (primeFactors-i)/3;
p = (p*mod_pow(3,t))%mod;
p = (p*i)%mod; // 注意还要乘上子集解。
break;
}
}
return p%mod;
}
};
本人是一个退役的Acm老狗,保研后生活比较闲,故想捡起之前所学的算法,写写博客也算是记录下自己的思路。