How can I find the occurence number of each suffix in a string? - c++

I want to find how many times each suffix of a string occurs in the original string in O(nlogn) or O(n) time.
For example, for string aba, suffix a appears twice, ba appears once, aba appears once.

Suffix Array Solution
Construct suffix tree of the string S along with LCP array. This will help in counting all the occurrences of each suffix.
without learning what suffix array and LCP are, its difficult to understand.
suffix array
LCP
kasai’s Algorithm for Construction of LCP array from Suffix Array
Let us take an example string and create its suffix array. Consider the string S = "ABABBAABB".
suffix positions(pos) Suffixes of S LCP array of S
5 AABB 1
0 ABABBAABB 2
6 ABB 3
2 ABBAABB 0
8 B 1
4 BAABB 2
1 BABBAABB 1
3 BBAABB 2
7 BB not Defined
First column(pos array) is the original starting points of sorted suffixes in Suffix Array. Let call second column as SuffixArray (we do not need to compute it, its just for visualization).
Now, as we know LCP[i]= the length of longest common prefix between SuffixArray[i] and SuffixArray[i+1]. e.g. LCP1=lcp("ABABBAABB","ABB")=2.
Let Count[i] = number of occurrences of suffix starting at position i.
for (int i = 0; i < n; )
{
int j=i;
while(LCP[j]==n-pos[j]){ // loop if SuffixArray[j] is a prefix of SuffixArray[j+1]
j++;
}
int incr=1;
for (int k = j-1; k>= i ; --k)
{
count[ pos[k] ] = incr;
incr++;
}
i=j+1;
}
This is highly optimized solution and if you look closely towards all steps, Complexity is O(n log n).
Hope it helps. Please go through everything again if you do not understand in the first try.
EDIT: There is tiny bug in this computation of count array. Basically my problem is to find the immediate next index in the LCP array which is smaller than current value. I am providing the correct implementation .
stack< int > stack;
count[ pos[n-1] ] = 1;
for(int i=n-2;i>=0;i--){
while(!stack.empty() and LCP[stack.top()]>=LCS[i]){
stack.pop();
}
if( LCP[i] == n-pos[i] ){
if (stack.empty())
{
count[ pos[i] ] = n-i ;
}else{
count[ pos[i] ] = stack.top()-i ;
}
}else{
count[ pos[i] ] = 1;
}
stack.push(i);
}
next smaller element in array

Related

Given an integer K and a matrix of size t x t. construct a string s consisting of first t lowercase english letters such that the total cost of s is K

I'm solving this problem and stuck halfway through, looking for help and a better method to tackle such a problem:
problem:
Given an integer K and a matrix of size t x t. we have to construct a string s consisting of the first t lowercase English letters such that the total cost of s is exactly K. it is guaranteed that there exists at least one string that satisfies given conditions. Among all possible string s which is lexicographically smallest.
Specifically the cost of having the ith character followed by jth character of the English alphabet is equal to cost[i][j].
For example, the cost of having 'a' followed by 'a' is denoted by cost[0][0] and the cost of having 'b' followed by 'c' is denoted by cost[1][3].
The total cost of a string is the total cost of two consecutive characters in s. for matrix cost is
[1 2]
[3 4],
and the string is "abba", then we have
the cost of having 'a' followed by 'b' is is cost[0][1]=2.
the cost of having 'b' followed by 'b' is is `cost0=4.
the cost of having 'b' followed by 'a' is cost0=3.
In total, the cost of the string "abba" is 2+4+3=9.
Example:
consider, for example, K is 3,t is 2, the cost matrix is
[2 1]
[3 4]
There are two strings that its total cost is 3. Those strings are:
"aab"
"ba"
our answer will be "aab" as it is lexicographically smallest.
my approach
I tried to find and store all those combinations of i, j such that it sums up to desired value k or is individual equals k.
for above example
v={
{2,1},
{3,4}
}
k = 3
and v[0][0] + v[0][1] = 3 & v[1][0] = 3 . I tried to store the pairs in an array like this std::vector<std::vector<std::pair<int, int>>>. and based on it i will create all possible strings and will store in the set and it will give me the strings in lexicographical order.
i stucked by writing this much code:
#include<iostream>
#include<vector>
int main(){
using namespace std;
vector<vector<int>>v={{2,1},{3,4}};
vector<pair<int,int>>k;
int size=v.size();
for(size_t i=0;i<size;i++){
for(size_t j=0;j<size;j++){
if(v[i][j]==3){
k.push_back(make_pair(i,j));
}
}
}
}
please help me how such a problem can be tackled, Thank you. My code can only find the individual [i,j] pairs that can be equal to desired K. I don't have idea to collect multiple [i,j] pairs which sum's to desired value and it also appears my approach is totally naive and based on brute force. Looking for better perception to solve the problems and implement it in the code. Thank you.
This is a backtracking problem. General approach is :
a) Start with the "smallest" letter for e.g. 'a' and then recurse on all the available letters. If you find a string that sums to K then you have the answer because that will be the lexicographically smallest as we are finding it from smallest to largest letter.
b) If not found in 'a' move to the next letter.
Recurse/backtrack can be done as:
Start with a letter and the original value of K
explore for every j = 0 to t and reducing K by cost[i][j]
if K == 0 you found your string.
if K < 0 then that path is not possible, so remove the last letter in the string, try other paths.
Pseudocode :
string find_smallest() {
for (int i = 0; i < t; i++) {
s = (char)(i+97)
bool value = recurse(i,t,K,s)
if ( value ) return s;
s = ""
}
return ""
}
bool recurse(int i, int t, int K, string s) {
if ( K < 0 ) {
return false;
}
if ( K == 0 ) {
return true;
}
for ( int j = 0; j < t; j++ ) {
s += (char)(j+97);
bool v = recurse(j, t, K-cost[i][j], s);
if ( v ) return true;
s -= (char)(j+97);
}
return false;
}
In your implementation, you would probably need another vector of vectors of pairs to explore all your candidates. Also another vector for updating the current cost of each candidate as it builds up. Following this approach, things start to get a bit messy (IMO).
A more clean and understandable option (IMO again) could be to approach the problem with recursivity:
#include <iostream>
#include <vector>
#define K 3
using namespace std;
string exploreCandidate(int currentCost, string currentString, vector<vector<int>> &v)
{
if (currentCost == K)
return currentString;
int size = v.size();
int lastChar = (int)currentString.back() - 97; // get ASCII code
for (size_t j = 0; j < size; j++)
{
int nextTotalCost = currentCost + v[lastChar][j];
if (nextTotalCost > K)
continue;
string nextString = currentString + (char)(97 + j); // get ASCII char
string exploredString = exploreCandidate(nextTotalCost, nextString, v);
if (exploredString != "00") // It is a valid path
return exploredString;
}
return "00";
}
int main()
{
vector<vector<int>> v = {{2, 1}, {3, 4}};
int size = v.size();
string initialString = "00"; // reserve first two positions
for (size_t i = 0; i < size; i++)
{
for (size_t j = 0; j < size; j++)
{
initialString[0] = (char)(97 + i);
initialString[1] = (char)(97 + j);
string exploredString = exploreCandidate(v[i][j], initialString, v);
if (exploredString != "00") { // It is a valid path
cout << exploredString << endl;
return 0;
}
}
}
}
Let us begin from the main function:
We define our matrix and iterate over it. For each position, we define the corresponding sequence. Notice that we can use indices to get the respective character of the English alphabet, knowing that in ASCII code a=97, b=98...
Having this initial sequence, we can explore candidates recursively, which lead us to the exploreCandidate recursive function.
First, we want to make sure that the current cost is not the value we are looking for. If it is, we leave immediately without even evaluating the following iterations for candidates. We want to do this because we are looking for the lexicographically smallest element, and we are not asked to provide information about all the candidates.
If the cost condition is not satisfied (cost < K), we need to continue exploring our candidate, but not for the whole matrix but only for the row corresponding to the last character. Then we can encounter two scenarios:
The cost condition is met (cost = K): if at some point of recursivity the cost is equal to our value K, then the string is a valid one, and since it will be the first one we encounter, we want to return it and finish the execution.
The cost is not valid (cost > K): If the current cost is greater than K, then we need to abort this branch and see if other branches are luckier. Returning a boolean would be nice, but since we want to output a string (or maybe not, depending on the statement), an option could be to return a string and use "00" as our "false" value, allowing us to know whether the cost condition has been met. Other options could be returning a boolean and using an output parameter (passed by reference) to contain the output string.
EDIT:
The provided code assumes positive non-zero costs. If some costs were to be zero you could encounter infinite recursivity, so you would need to add more constraints in your recursive function.

Array-Sum Operation

I have written this code using vector. Some case has been passed but others show timeout termination error.
The problem statement is:-
You have an identity permutation of N integers as an array initially. An identity permutation of N integers is [1,2,3,...N-1,N]. In this task, you have to perform M operations on the array and report the sum of the elements of the array after each operation.
The ith operation consists of an integer opi.
If the array contains opi, swap the first and last elements in the array.
Else, remove the last element of the array and push opi to the end of the array.
Input Format
The first line contains two space-separated integers N and M.
Then, M lines follow denoting the operations opi.
Constraints :
2<=N,M <= 10^5
1 <= op <= 5*10^5
Output Format
Print M lines, each containing a single integer denoting the answer to each of the M operations.
Sample Input 0
3 2
4
2
Sample Output 0
7
7
Explanation 0
Initially, the array is [1,2,3].
After the 1st operation, the array becomes[1,2,4] as opi = 4, as 4 is not present in the current array, we remove 3 and push 4 to the end of the array and hence, sum=7 .
After 2nd operation the array becomes [4,2,1] as opi = 2, as 2 is present in the current array, we swap 1 and 4 and hence, sum=7.
Here is my code:
#include <bits/stdc++.h>
using namespace std;
int main()
{
long int N,M,op,i,t=0;
vector<long int > g1;
cin>>N>>M;
if(N>=2 && M>=2) {
g1.reserve(N);
for(i = 1;i<=N;i++) {
g1.push_back(i);
}
while(M--) {
cin>>op;
auto it = find(g1.begin(), g1.end(), op);
if(it != (g1.end())) {
t = g1.front();
g1.front() = g1.back();
g1.back() = t;
cout<<accumulate(g1.begin(), g1.end(), 0);
cout<<endl;
}
else {
g1.back() = op;
cout<<accumulate(g1.begin(), g1.end(), 0);
cout<<endl;
}
}
}
return 0;
}
Please Suggest changes.
Looking carefully in question you will find that the operation are made only on the first and last element. So there is no need to involve a whole vector in it much less calculating the sum. we can calculate the whole sum of the elements except first and last by (n+1)(n-2)/2 and then we can manipulate the first and last element in the question. We can also shorten the search by using (1<op<n or op==first element or op == last element).
p.s. I am not sure it will work completely but it certainly is faster
my guess, let take N = 3, op = [4, 2]
N= [1,2,3]
sum = ((N-2) * (N+1)) / 2, it leave first and last element, give the sum of numbers between them.
we need to play with the first and last elements. it's big o(n).
function performOperations(N, op) {
let out = [];
let first = 1, last = N;
let sum = Math.ceil( ((N-2) * (N+1)) / 2);
for(let i =0;i<op.length;i++){
let not_between = !(op[i] >= 2 && op[i] <= N-1);
if( first!= op[i] && last != op[i] && not_between) {
last = op[i];
}else {
let t = first;
first = last;
last = t;
}
out.push(sum + first +last)
}
return out;
}

How to find all substrings that start and end with 1?

You are given a string of 0’s and 1’s you have to find all substrings in the string which starts and end with a 1.
For example, given 0010110010, output should be the six strings:
101
1011
1011001
11
11001
1001
Obviously there is an O(N^2) solution, but I'm looking for a solution with complexity on the order of O(N). Is it possible?
Obviously there is an O(N^2) solution, but I'm looking for a solution with complexity on the order of O(N). Is it possible?
Let k be the number of 1s in our input string. Then there are O(k^2) such substrings. Enumerating them must take at least O(k^2) time. If k ~ N, then enumerating them must take O(N^2) time.
The only way to get an O(N) solution is if we add the requirement that k is o(sqrt(N)). There cannot be an O(N) solution in the general case with no restriction on k.
An actual O(k^2) solution is straightforward:
std::string input = ...;
std::vector<size_t> ones;
ones.reserve(input.size());
// O(N) find the 1s
for (size_t idx = 0; idx < input.size(); ++idx) {
if (input[idx] == '1') {
ones.push_back(idx);
}
}
// O(k^2) walk the indices
for (size_t i = 0; i < ones.size(); ++i) {
for (size_t j = i+1; j < ones.size(); ++j) {
std::cout << input.substr(i, j - i + 1) << '\n';
}
}
Update We have to account for the lengths of the substrings as well as the number of them. The total length of all the strings is O(k * N), which is strictly greater than the previously claimed bound of O(k^2). Thus, the o(sqrt(N)) bound on k is insufficient - we actually need k to be O(1) in order to yield an O(N) solution.
You can find the same in O(n) with the following steps :
1. Count the number of 1's.
2. Let # of 1's be x, we return x(x-1)/2.
This quite trivially counts the number of possible pairs of 1's.
The code itself is probably worth trying yourself!
EDIT:
If you want to return the substrings themselves, you must restrict the number of 1's in your substring in order to get some sort of O(N) solution (or really O(x) where x is your # of 1's) , as enumerating them in itself cannot be reduced in a general case from O(N^2) time complexity.
If you just need the number of substrings, and not the substrings themselves, you could probably pull it off by counting the number of pairs after doing an initial O(n) sum of the number of 1's you encounter
Assuming N is supposed to be the number of 1s in your string (or at least proportional to it, which is reasonable assuming a constant probability of 1 for each character):
If you need the substrings themselves, there's going to be N(N-1)/2, which is quadratic, so it's completely impossible to be less complex than quadratic.
import java.util.*;
public class DistictSubstrings {
public static void main(String args[]) {
// a hash set
Scanner in = new Scanner(System.in);
System.out.print("Enter The string");
String s = in.nextLine();
int L = s.length();
Set<String> hs = new HashSet<String>();
// add elements to the hash set
for (int i = 0; i < L; ++i) {
for (int j = 0; j < L-i ; ++j) {
if(s.charAt(j)=='1'&&s.charAt(j+i)=='1')
{
hs.add(s.substring(j, j+i + 1));
}
}
}
Iterator it=hs.iterator();
System.out.println("the string starts and endswith 1");
System.out.println(hs.size());
while(it.hasNext())
{
System.out.println(it.next()+" ");
}
String s="1001010001";
for(int i=0;i<=s.length()-1;i++)
{
for(int j=0;j<=s.length()-1;j++)
{
if(s.charAt(j)=='1' && s.charAt(i)=='1' && i<j)
{
System.out.println(s.substring(i,j+1));
}
}
}
The following python code will help you to find all substrings that starts and ends with 1.
# -*- coding: utf-8 -*-
"""
Created on Tue Sep 26 14:25:14 2017
#author: Veeramani Natarajan
"""
# Python Implementation to find all substrings that start and end with 1
# Function to calculate the count of sub-strings
def calcCount(mystring):
cnt=-1
index=0
while(index<len(mystring)):
if(mystring[index]=='1'):
cnt += 1
index += 1
return cnt
mystring="0010110010";
index=0;
overall_cnt=0
while(index<len(mystring)):
if(mystring[index]=='1'):
partcount=calcCount(mystring[index:len(mystring)])
overall_cnt=overall_cnt+partcount
# print("index is",index)
# print("passed string",mystring[index:len(mystring)])
# print("Count",partcount,"overall",overall_cnt)
index=index+1
# print the overall sub strings count
print (overall_cnt)
Note:
Though this is not O(N) solution, i believe it will help someone to understand the python implementation of the above problem statement.
O(n) solution is definitely possible using DP.
We take an array of pairs where the first element in each pair denotes the number of substrings upto that index and the second element denotes the number of substrings starting with 1 up to but not including that index. (So, if the char at that index is 1, the second element won't count the substring [1, 1])
We simply iterate through the array and build the solution incrementally as we do in DP and after the end of the loop, we have the final value in the pair's first element in the last index of our array. Here's the code:
int getoneonestrings(const string &str)
{
int n = str.length();
if (n == 1)
{
return 0;
}
vector< pair<int, int> > dp(n, make_pair(0, 0));
for (int i = 1; i < n; i++)
{
if (str[i] == '0')
{
dp[i].first = dp[i - 1].first;
}
else
{
dp[i].first = dp[i - 1].first + dp[i - 1].second +
(str[i - 1] == '1' ? 1 : 0);
}
dp[i].second = dp[i - 1].second + (str[i - 1] == '1' ? 1 : 0);
}
return dp[n - 1].first;
}

How to reduce the time complexity to find the longest zigzag sequence?

I was trying to solve the problem zig zag sequences on top coder.The time complexity of my code is O(n*n). How can I reduce it to O(n) or O(nlog (n))
Pseudo code or explanation of the algorithm will be really helpful to me
Here is the problem statement.
Problem Statement
A sequence of numbers is called a zig-zag sequence if the differences between successive numbers strictly alternate between positive and negative. The first difference (if one exists) may be either positive or negative. A sequence with fewer than two elements is trivially a zig-zag sequence.
For example, 1,7,4,9,2,5 is a zig-zag sequence because the differences (6,-3,5,-7,3) are alternately positive and negative. In contrast, 1,4,7,2,5 and 1,7,4,5,5 are not zig-zag sequences, the first because its first two differences are positive and the second because its last difference is zero.
Given a sequence of integers, sequence, return the length of the longest subsequence of sequence that is a zig-zag sequence. A subsequence is obtained by deleting some number of elements (possibly zero) from the original sequence, leaving the remaining elements in their original order.
And here is my code
#include <iostream>
#include<vector>
#include<cstring>
#include<cstdio>
using namespace std;
class ZigZag
{
public:
int dp[200][2];
void print(int n)
{
for(int i=0;i<n;i++)
{
cout<<dp[i][0]<<endl;
}
}
int longestZigZag(vector<int> a)
{
int n=a.size();
//int dp[n][2];
for(int i=0;i<n;i++)
{
cout<<a[i]<<" "<<"\t";
}
cout<<endl;
memset(dp,sizeof(dp),0);
dp[0][1]=dp[0][0]=1;
for(int i=1;i<n;i++)
{
dp[i][1]=dp[i][0]=1;
for(int j=0;j<i;j++)
{
if(a[i]<a[j])
{
dp[i][0]=max(dp[j][1]+1,dp[i][0]);
}
if(a[j]<a[i])
{
dp[i][1]=max(dp[j][0]+1,dp[i][1]);
}
}
cout<<dp[i][1]<<"\t"<<dp[i][0]<<" "<<i<<endl;
//print(n);
}
cout<<dp[n-1][0]<<endl;
return max(dp[n-1][0],dp[n-1][1]);
}
};
U can do it in O(n) using a greedy approach. Take the first non-repeating number - this is the first number of your zigzag subsequence. Check whether the next number in the array is lesser than or greater than the first number.
Case 1: If lesser, check the next element to that and keep going till you find the least element (ie) the element after that would be greater than the previous element. This would be your second element.
Case 2: If greater, check the next element to that and keep going till you find the greatest element (ie) the element after that would be lesser than the previous element. This would be your second element.
If u have used Case 1 to find the second element, use Case 2 to find the third element or vice-versa. Keep alternating between these two cases till u have no more elements in the original sequence. The resultant numbers u get would form the longest zigzag subsequence.
Eg: { 1, 17, 5, 10, 13, 15, 10, 5, 16, 8 }
The resulting subsequence:
1 -> 1,17 (Case 2) -> 1,17,5 (Case 1) -> 1,17,5,15 (Case 2) -> 1,17,5,15,5 (Case 1) -> 1,17,5,15,5,16 (Case 2) -> 1,17,5,15,5,16,8 (Case 1)
Hence the length of the longest zigzag subsequence is 7.
U can refer to sjelkjd's solution for an implementation of this idea.
As the subsequence should not be necessarily contiguous you can't make it O(n). In a worst case the complexity is O(2^n). Howewer, I did some checks to cut off subtrees as soon as possible.
int maxLenght;
void test(vector<int>& a, int sign, int last, int pos, int currentLenght) {
if (maxLenght < currentLenght) maxLenght = currentLenght;
if (pos >= a.size() || pos >= a.size() + currentLenght - maxLenght) return;
if (last != a[pos] && (last - a[pos] >= 0) != sign)
test(a,!sign,a[pos],pos+1,currentLenght+1);
test(a,sign,last,pos+1,currentLenght);
}
int longestZigZag(vector<int>& a) {
maxLenght = 0;
test(a,0,a[0],1,1);
test(a,!0,a[0],1,1);
return maxLenght;
}
You can use RMQs to remove the inner for-loop. When you find the answer for dp[i][0] and dp[i][1], save it in two RMQ trees - say, RMQ0 and RMQ1 - just like you're doing now with the two rows of the dp array. So, when you calculate dp[i][0], you put the value dp[i][0] on position a[i] in RMQ0, meaning that there is a zig-zag sequence with length dp[i][0] ending increasingly with number a[i].
Then, in order to calculate dp[i + 1][0], you don't have to loop through all the numbers between 0 and i. Instead, you can query RMQ0 for the largest number on position > a[i + 1]. This will give you the longest zig-zag subsequence ending with a number larger than the current one - i.e. the longest one that can be continued decreasingly with the number a[i + 1]. Then you can do the same for RMQ1 for the other half of the zig-zag subsequences.
Since you can implement dynamic RMQ with query complexity of O(log N), this gives you an overall complexity of O(N log N).
You can solve this problem in O(n) time and O(n) extra space.
Algorithm goes as follows.
Store the difference of alternative term in new array of size n-1
Now traverse the new array and just check whether the product of alternative term is less then zero or not.
Increment result accordingly. If while traversing you find that array is product is more than zero in that case you store the result and again start counting for the rest of the element in difference array.
Find the maximum among them store it into result, and return (result+1)
Here is it's implementation in C++
#include <iostream>
#include <vector>
using namespace std;
int main()
{
ios_base::sync_with_stdio(false);
int n;
cin>>n;
vector<int> data(n);
for(int i = 0; i < n; i++)
cin>>data[i];
vector<int> diff(n-1);
for(int i = 1; i < n; i++)
diff[i-1] = data[i]-data[i-1];
int res = 1;
if( n < 2)
cout<<res<<"\n";
else
{
int temp_idx = 0;
for(int i = 1; i < n-1; i++)
{
if(diff[i]*diff[i-1] < 0)
{
temp_idx++;
res++;
}
else
{
res = max(res,temp_idx);
temp_idx = 1;
}
}
cout<<res+1<<"\n";
}
return 0;
}
This is a purely theoretical solution. This is how you would solve it if you would be asked for it in an academical environment, standing next to the chalkboard.
The solution to the problem can be created using dynamic programming:
The subproblem has the form of: if I have an element x of the sequence, what is the longest subsequence that is ending on that element?
Then you can work out your solution using recursive calls, which should look something like this (the directions of the relations might be wrong, I haven't checked it):
S - given sequence (array of integers)
P(i), Q(i) - length of the longest zigzag subsequence on elements S[0 -> i] inclusive (the longest sequence that is correct, where S[i] is the last element)
P(i) = {if i == 0 then 1
{max(Q(j) if A[i] < A[j] for every 0 <= j < i)
Q(i) = {if i == 0 then 0 #yields 0 because we are pedantic about "is zig the first relation, or is it zag?". If we aren't, then this can be a 1.
{max(P(j) if A[i] > A[j] for every 0 <= j < i)
This should be O(n) with the right memoization (storing each output of Q(i) and P(i)), because each subproblem is only computed once: n*|P| + n*|Q|.
These calls return the length of the solution - the actual result can be found by storing "parent pointer" whenever a max value is found, and then traversing backwards on these pointers.
You can avoid the recursion simply by substituting function calls with array lookups: P[i] and Q[i], and using a for loop.

simpest way to get the longest sequence of sorted elements from a given unsorted integer vector in c++

I have an unsorted array and need to extract the longest sequence of sorted elements.
For instance
A = 2,4,1,7,4,5,0,8,65,4,2,34
here 0,8,65 is my target sequence
I need to keep track of the index where this sequence starts
You can do it in linear time O(N) with this algorithm: construct vector len of the same size N as the original vector, such that len[i] contains the length of the longest consecutive ascending run to which element seq[i] belongs.
The value of len[i] can be calculated as follows:
len[0] = 1;
for (int i = 1 ; i != N ; i++) {
len[i] = seq[i-1] >= seq[i] ? 1 : len[i-1]+1;
}
With len in hand, find the index of max(len) element. This is the last element of your run. Track back to len[j] == 1 to find the initial element of the run.
seq len
--- ---
2 1
4 2
1 1
7 2
4 1
5 2
0 1
8 2
65 3 << MAX
4 1
2 1
34 2
Note that at each step of the algorithm you need only the element len[i-1] to calculate len, so you can optimize for constant space by dropping vector representation of len and keeping the prior one, the max_len, and max_len_index.
Here is this algorithm optimized for constant space. Variable len represents len[i-1] from the linear-space algorithm.
int len = 1, pos = 0, maxlen = 1, current_start = 0;
for (int i = 1 ; i < seq.size() ; i++) {
if (seq[i] > seq[i-1]) {
len++;
if (len > maxlen) {
maxlen = len;
pos = current_start;
}
} else {
len = 1;
current_start = i;
}
}
Here is a link to this program on ideone.
You need 4 indexes (begin, end, tmp_begin, tmp_end). Iterate through the original array using tmp_begin, tmp_end as the work indexes and each time you find a longer sorted sequence update begin and end indices.
To check that a subsequence is sorted, you have to check that element at i is greater than element at i-- for each pair of consecutive items in the subsequence.
In the end: print all the elements in the original array starting at begin and ending at end.
for(int i=0;i<size_of_array;i++)
{
iterate++;
after=array[iterate];
if(after>before) {current_counter++;} else {current_counter=0;}
if(max_counter<current_counter) max_counter=current_counter;
before=array[iterate];
}
printf(" maximum length=%i ",max_counter);