Sunday 27 August 2017

Maximum Subarray Problem in Linear running time-CLRS

Well, I'd to do this later or sooner. I was revising CLRS, and (again) was stuck at some questions. So I wondered-thought-wrote repeatedly, and found their  respective solutions. But then I wondered what did I do the first time? 

So, this is a reference to my future self as well as people who may find it useful. 


Q 4.1-5 CLRS 

So, this question asks us to write an algorithm to implement the Maximum Subarray Problem in Linear running time. The problems that initially come into mind are:
  1.  Addition of each element should be done in constant time.
  2. We're allowed to loop only once through the array given to us.
So, there seem three possible solutions to these problems:
  1.  Do some freaking magic trick, and decide that the current element shall stay in the maximum subarray, while also changing the values of the starting as well as ending indices of the MSA.
  2. Make a structure in $O(n)$, and then use that structure for each current value, in constant time, thus taking a total of $O(n)+O(n)=O(n)$ time.
  3.   Making and updating a structure in constant time for every new value.
The third one is the one I'll choose(because I'm dumb and don't know magic as well.)

The Plan.

The plan is to constantly update two arrays. One is the MSA: Maximum subarray, and the second one is the LSA: Last subarray( pardon me for the nomenclature though). So the MSA keeps track of the Maximal subarray encountered until now, whereas the LSA keeps track of the maximum subarray that contains the current (last) element. 

Here is the java-code for the algorithm, even though I like common -lisp more. 
 class MSALinear{  
      public static void main(String args[]){  
      int A[] = {13,-3,-25,20,-3,-16,-23,18,20,-7,12,-5,-22,15,-4,7};  
      int n = A.length ;  
      //System.out.print("Length of this array:"+n);  
      int SMSA = A[0], SLSA = A[0], a = 0,b=0,k=0,j=0;  
      for(int i=1;i<n;i++)  
      {  
           if(A[i]>SMSA)//The current element is more than the sum total of the maximum subarray.  
           {  
                SMSA = A[i] ;  
                a=i;  
                b=i;  
                k=i;  
                j=i;  
           }  
           else if(A[i]+SLSA>SMSA)//The sum of the current element and the maximum array containing the second last element is more than the sum total of the MSA  
           {  
                SMSA = A[i]+SLSA;  
                SLSA = SMSA ;  
                a = k ;  
                j=i;  
                b=i ;  
           }  
           else if(A[i]>SLSA+A[i])//The current element is more than the sum of the Maximum last subarray and the current element, thus we can change LSA  
           {  
                SLSA = A[i] ;  
                j=i;  
                k=i ;  
           }  
           else// The current element is included in the LSA  
           {  
                SLSA = SLSA+A[i] ;  
                j=i;  
           }  
      }  
      System.out.print("The MSA starts from "+a+" and ends at "+b+" with the sum :"+SMSA);  
      }  
 }  

    Here, SLSA is the sum of the LSA, whereas SMSA is the sum of the MSA. $a$ and $b$ are the starting and ending indices of the MSA respectively, whereas $k$ and $j$ are the starting and ending indices of the LSA respectively. 

Points to notice:

  1. The code has only one loop, thus it runs in $O(n)$ time.
  2. Every condition has $j=i$ condition in it, therefore it is redundant. I'm lazy too.
  3. $j$ always equals $i$. I think this point should be above point-2. Duh. 
  4. I took the liberty of taking the array given in CLRS. Lazy. Told 'ya.
     

2 comments:

  1. I love your blog and your words on it and elsewhere. You're an inspiration. <3 I hope your marks improve.

    ReplyDelete
    Replies
    1. Thank you senor/senorita Anonymous! Marks and I have a relationship that can't be expressed in mere words. An inverse relationship between the work I did and the marks I get, would be an apt mathematical description of the relationship.

      Delete

1295D - Same GCDs

 1295D - Same GCDs Link to the problem :  https://codeforces.com/problemset/problem/1295/D I had to see the tutorial to understand this. $$ ...