The above is the link to the problem. I have written a solution using upper_bound function which is getting TLE for 2 out of 13 test cases and barely passing one 1 testcase. Any help in either reducing time in my code or telling the solution will not be accepted with this method will be appreciated. Thank you.(I have put comments in my code to help in understanding.)
#include<bits/stdc++.h>
#include <iostream>
using namespace std;
void solve(){
int n,m;
string s;
cin>>n>>s>>m;
//Values is like a 2d vector which stores all the occurences of a in val[0], that of b in val[1],etc
//I also put a value n at the end of all the alphabets to mark a end point.
//indexes a zero based index
vector<vector<int>> values(26);
for(int i=0;i<n;i++){
values[s[i]-'a'].push_back(i);
}
for(int i=0;i<26;i++){
values[i].push_back(n);
}
//In the above two loop i have filled values vector with all the indexes of all the alphabets
//Note : All the occurences are sorted and there is a end point n present in all the vectors
//containing the occurencesof each element.
//I am initially setting my solution as INT_MAX so if i have a solution lower then this by the end
//of the program i will print that solution(lowest answer) else i will print -1.
int sol=INT_MAX;
//We always have to start our subsequences with the letter a so i have decided that i will create
//a loop with in which i try to find all the answers which start with each occurences of a.
for(int i=0;i<values[0].size()-1;i++){
//The temp variable is just to there to check the size of the subsequence will be m.
int temp=m-1;
//K is used to identify the position of the alphabet i will be finding next (k%26).
//K is one since we already have a.
int k=1;
//Start is the position of the alphabet a from which we are going to find our answer/subsequence.
int start=values[0][i];
//If there are not enough element in the string to find a answer we get out of loop.
if(start+m-1>=n)
break;
//In the beginning we name end=start as the subsequence we have found till now is only till position start
int end=start;
//In this loop we will find all m element of the subsequence
while(temp!=0){
//D is the alphabet to find.
int d=k%26;
//it iterator gives us the alphabet we need to find and we put the position of this alphabet in
//end.Note we find upper_bound to end as end was the position of our last element
auto it=upper_bound(values[d].begin(),values[d].end(),end);
end=values[d][it-values[d].begin()];
//If end==n we won't able to complete thi subsequence or any new subsequence so we
//can finish the program here.
if(end==n){
if(sol==INT_MAX){
cout<<-1<<"\n";
return;
}
//SInce we need to print the total numbers to deleted it is sol-m
cout<<sol-m<<"\n";
return;
}
//If before finding all the element,we find that the current to be solution is
//greater then actual solution, we can skip this partcular subsequence.
if(end-start+1>=sol){
break;
}
temp--;
k++;
}
//if end<n i.e there is a soolution
if(end!=n)
sol=min(sol,end-start+1);
//No other soolution is smaller then this so we can end.
if(sol==m)
break;
}
//This is discussed above.
if(sol==INT_MAX){
cout<<-1<<"\n";
return;
}
cout<<sol-m<<"\n";
}
int main(){
#ifndef ONLINE_JUDGE
freopen("input.txt","r",stdin);
freopen("output.txt","w",stdout);
freopen("error.txt","w",stderr);
#endif
ios_base::sync_with_stdio(false);
cin.tie(NULL);
cout.tie(NULL);
int t=1;
cin>>t;
while(t--) {
solve();
}
return 0;
}
Code without comments
#include<bits/stdc++.h>
#include <iostream>
using namespace std;
void solve(){
int n,m;
string s;
cin>>n>>s>>m;
vector<vector<int>> values(26);
for(int i=0;i<n;i++){
values[s[i]-'a'].push_back(i);
}
for(int i=0;i<26;i++){
values[i].push_back(n);
}
int sol=INT_MAX;
for(int i=0;i<values[0].size()-1;i++){
int temp=m-1;
int k=1;
int start=values[0][i];
if(start+m-1>=n)
break;
int end=start;
while(temp!=0){
int d=k%26;
auto it=upper_bound(values[d].begin(),values[d].end(),end);
end=values[d][it-values[d].begin()];
if(end==n){
if(sol==INT_MAX){
cout<<-1<<"\n";
return;
}
cout<<sol-m<<"\n";
return;
}
if(end-start+1>=sol){
break;
}
temp--;
k++;
}
if(end!=n)
sol=min(sol,end-start+1);
if(sol==m)
break;
}
if(sol==INT_MAX){
cout<<-1<<"\n";
return;
}
cout<<sol-m<<"\n";
}
int main(){
#ifndef ONLINE_JUDGE
freopen("input.txt","r",stdin);
freopen("output.txt","w",stdout);
freopen("error.txt","w",stderr);
#endif
ios_base::sync_with_stdio(false);
cin.tie(NULL);
cout.tie(NULL);
int t=1;
cin>>t;
while(t--) {
solve();
}
return 0;
}
Auto comment: topic has been updated by SagarPrasad (previous revision, new revision, compare).
Auto comment: topic has been updated by SagarPrasad (previous revision, new revision, compare).
The complexity of your code is approximately O( (n^2/(26^2))*log(n/26) ) i.e of order 10^10 operations, which gets you TLE. try binary lifting