Maksimālā produkta apakšgrupa | 2. komplekts (izmantojot divus šķērsojumus)

Ja masīvs satur gan pozitīvus, gan negatīvus veselus skaitļus, atrodiet maksimālā produkta apakšmasīva reizinājumu. Paredzamā laika sarežģītība ir O(n), un var izmantot tikai O(1) papildu vietu.

Piemēri:  

Input: arr[] = {6 -3 -10 0 2} Output: 180 // The subarray is {6 -3 -10} Input: arr[] = {-1 -3 -10 0 60} Output: 60 // The subarray is {60} Input: arr[] = {-1 -2 -3 4} Output: 24 // The subarray is {-2 -3 4} Input: arr[] = {-10} Output: 0 // An empty array is also subarray // and product of empty subarray is // considered as 0. 

Mēs esam apsprieduši šīs problēmas risinājumu šeit . 
Šajā rakstā tiek apspriests interesants risinājums. Ideja ir balstīta uz faktu, ka kopējais maksimālais produkts ir ne vairāk kā šādi divi: 

  1. Maksimālais produkts šķērsošanā no kreisās uz labo pusi.
  2. Maksimālais produkts šķērsošanā no labās uz kreiso pusi

Piemēram, apsveriet iepriekš minēto trešo parauga ievadi {-1 -2 -3 4}. Ja mēs šķērsosim masīvu tikai virzienā uz priekšu (ņemot vērā -1 kā daļu no izvades), maksimālā reizinājums būs 2. Ja mēs šķērsosim masīvu atpakaļ virzienā (uzskatot 4 kā daļu no izvades), maksimālā reizinājums būs 24, t.i.; { -2 -3 4}. 
Viena svarīga lieta ir rīkoties ar 0. Mums ir jāaprēķina jauna uz priekšu (vai atpakaļejošu) summa, kad mēs redzam 0.

Zemāk ir iepriekš minētās idejas īstenošana: 

C++
   // C++ program to find maximum product subarray   #include       using     namespace     std  ;   // Function for maximum product   int     max_product  (  int     arr  []     int     n  )   {      // Initialize maximum products in forward and      // backward directions      int     max_fwd     =     INT_MIN       max_bkd     =     INT_MIN  ;      // Initialize current product      int     max_till_now     =     1  ;      //check if zero is present in an array or not      bool     isZero  =  false  ;          // max_fwd for maximum contiguous product in      // forward direction      // max_bkd for maximum contiguous product in      // backward direction      // iterating within forward direction in array      for     (  int     i  =  0  ;     i   <  n  ;     i  ++  )      {      // if arr[i]==0 it is breaking condition      // for contiguous subarray      max_till_now     =     max_till_now  *  arr  [  i  ];      if     (  max_till_now     ==     0  )      {         isZero  =  true  ;      max_till_now     =     1  ;      continue  ;      }      if     (  max_fwd      <     max_till_now  )     // update max_fwd      max_fwd     =     max_till_now  ;      }      max_till_now     =     1  ;      // iterating within backward direction in array      for     (  int     i  =  n  -1  ;     i  >=  0  ;     i  --  )      {      max_till_now     =     max_till_now     *     arr  [  i  ];      if     (  max_till_now     ==     0  )      {      isZero  =  true  ;      max_till_now     =     1  ;      continue  ;      }      // update max_bkd      if     (  max_bkd      <     max_till_now  )      max_bkd     =     max_till_now  ;      }      // return max of max_fwd and max_bkd      int     res     =     max  (  max_fwd       max_bkd  );      // Product should not be negative.      // (Product of an empty subarray is      // considered as 0)      if  (  isZero  )      return     max  (  res       0  );      return     res  ;   }   // Driver Program to test above function   int     main  ()   {      int     arr  []     =     {  -1       -2       -3       4  };      int     n     =     sizeof  (  arr  )  /  sizeof  (  arr  [  0  ]);      cout      < <     max_product  (  arr       n  )      < <     endl  ;      return     0  ;   }   
Java
   // Java program to find   // maximum product subarray   import     java.io.*  ;   class   GFG   {   // Function for maximum product   static     int     max_product  (  int     arr  []       int     n  )   {      // Initialize maximum products in      // forward and backward directions      int     max_fwd     =     Integer  .  MIN_VALUE        max_bkd     =     Integer  .  MIN_VALUE  ;      //check if zero is present in an array or not      boolean     isZero  =  false  ;      // Initialize current product      int     max_till_now     =     1  ;      // max_fwd for maximum contiguous      // product in forward direction      // max_bkd for maximum contiguous      // product in backward direction      // iterating within forward      // direction in array      for     (  int     i     =     0  ;     i      <     n  ;     i  ++  )      {      // if arr[i]==0 it is breaking      // condition for contiguous subarray      max_till_now     =     max_till_now     *     arr  [  i  ]  ;      if     (  max_till_now     ==     0  )      {      isZero  =  true  ;      max_till_now     =     1  ;      continue  ;      }          // update max_fwd      if     (  max_fwd      <     max_till_now  )      max_fwd     =     max_till_now  ;      }      max_till_now     =     1  ;      // iterating within backward      // direction in array      for     (  int     i     =     n     -     1  ;     i     >=     0  ;     i  --  )      {      max_till_now     =     max_till_now     *     arr  [  i  ]  ;      if     (  max_till_now     ==     0  )      {      isZero  =  true  ;      max_till_now     =     1  ;      continue  ;      }      // update max_bkd      if     (  max_bkd      <     max_till_now  )      max_bkd     =     max_till_now  ;      }      // return max of max_fwd and max_bkd      int     res     =     Math  .     max  (  max_fwd       max_bkd  );      // Product should not be negative.      // (Product of an empty subarray is      // considered as 0)      if  (  isZero  )      return     Math  .  max  (  res       0  );          return     res  ;   }   // Driver Code   public     static     void     main     (  String  []     args  )   {      int     arr  []     =     {  -  1       -  2       -  3       4  };      int     n     =     arr  .  length  ;      System  .  out  .  println  (     max_product  (  arr       n  )     );   }   }   // This code is contributed by anuj_67.   
Python3
   # Python3 program to find   # maximum product subarray   import   sys   # Function for maximum product   def   max_product  (  arr     n  ):   # Initialize maximum products   # in forward and backward directions   max_fwd   =   -  sys  .  maxsize   -   1   max_bkd   =   -  sys  .  maxsize   -   1   #check if zero is present in an array or not   isZero  =  False  ;   # Initialize current product   max_till_now   =   1   # max_fwd for maximum contiguous   # product in forward direction   # max_bkd for maximum contiguous   # product in backward direction   # iterating within forward   # direction in array   for   i   in   range  (  n  ):   # if arr[i]==0 it is breaking   # condition for contiguous subarray   max_till_now   =   max_till_now   *   arr  [  i  ]   if   (  max_till_now   ==   0  ):   isZero  =  True   max_till_now   =   1  ;   continue   if   (  max_fwd    <   max_till_now  ):   #update max_fwd   max_fwd   =   max_till_now   max_till_now   =   1   # iterating within backward   # direction in array   for   i   in   range  (  n   -   1     -  1     -  1  ):   max_till_now   =   max_till_now   *   arr  [  i  ]   if   (  max_till_now   ==   0  ):   isZero  =  True   max_till_now   =   1   continue   # update max_bkd   if   (  max_bkd    <   max_till_now  )   :   max_bkd   =   max_till_now   # return max of max_fwd and max_bkd   res   =   max  (  max_fwd     max_bkd  )   # Product should not be negative.   # (Product of an empty subarray is   # considered as 0)   if   isZero  ==  True   :   return   max  (  res     0  )   return   res   # Driver Code   arr   =   [  -  1     -  2     -  3     4  ]   n   =   len  (  arr  )   print  (  max_product  (  arr     n  ))   # This code is contributed   # by Yatin Gupta   
C#
   // C# program to find maximum product   // subarray   using     System  ;      class     GFG     {      // Function for maximum product      static     int     max_product  (  int     []  arr       int     n  )      {          // Initialize maximum products in       // forward and backward directions      int     max_fwd     =     int  .  MinValue           max_bkd     =     int  .  MinValue  ;          // Initialize current product      int     max_till_now     =     1  ;          // max_fwd for maximum contiguous       // product in forward direction      // max_bkd for maximum contiguous       // product in backward direction      // iterating within forward       // direction in array      for     (  int     i     =     0  ;     i      <     n  ;     i  ++  )      {          // if arr[i]==0 it is breaking       // condition for contiguous subarray      max_till_now     =     max_till_now     *     arr  [  i  ];          if     (  max_till_now     ==     0  )      {      max_till_now     =     1  ;      continue  ;      }          // update max_fwd      if     (  max_fwd      <     max_till_now  )         max_fwd     =     max_till_now  ;      }          max_till_now     =     1  ;          // iterating within backward       // direction in array      for     (  int     i     =     n     -     1  ;     i     >=     0  ;     i  --  )      {      max_till_now     =     max_till_now     *     arr  [  i  ];      if     (  max_till_now     ==     0  )      {      max_till_now     =     1  ;      continue  ;      }          // update max_bkd      if     (  max_bkd      <     max_till_now  )      max_bkd     =     max_till_now  ;      }          // return max of max_fwd and max_bkd      int     res     =     Math  .     Max  (  max_fwd       max_bkd  );          // Product should not be negative.      // (Product of an empty subarray is      // considered as 0)      return     Math  .  Max  (  res       0  );      }          // Driver Code      public     static     void     Main     ()         {      int     []  arr     =     {  -  1       -  2       -  3       4  };      int     n     =     arr  .  Length  ;          Console  .  Write  (     max_product  (  arr       n  )     );      }   }   // This code is contributed by nitin mittal.   
PHP
      // PHP program to find maximum    // product subarray   // Function for maximum product   function   max_product  (   $arr     $n  )   {   // Initialize maximum products   // in forward and backward   // directions   $max_fwd   =   PHP_INT_MIN  ;   $max_bkd   =   PHP_INT_MIN  ;   // Initialize current product   $max_till_now   =   1  ;   // max_fwd for maximum contiguous    // product in forward direction   // max_bkd for maximum contiguous   // product in backward direction   // iterating within forward direction   // in array   for   (  $i   =   0  ;   $i    <   $n  ;   $i  ++  )   {   // if arr[i]==0 it is   // breaking condition   // for contiguous subarray   $max_till_now   =   $max_till_now   *   $arr  [  $i  ];   if   (  $max_till_now   ==   0  )   {   $max_till_now   =   1  ;   continue  ;   }   // update max_fwd   if   (  $max_fwd    <   $max_till_now  )   $max_fwd   =   $max_till_now  ;   }   $max_till_now   =   1  ;   // iterating within backward    // direction in array   for  (  $i   =   $n   -   1  ;   $i   >=   0  ;   $i  --  )   {   $max_till_now   =   $max_till_now   *   $arr  [  $i  ];   if   (  $max_till_now   ==   0  )   {   $max_till_now   =   1  ;   continue  ;   }   // update max_bkd   if   (  $max_bkd    <   $max_till_now  )   $max_bkd   =   $max_till_now  ;   }   // return max of max_fwd   // and max_bkd   $res   =   max  (  $max_fwd     $max_bkd  );   // Product should not be negative.   // (Product of an empty subarray is   // considered as 0)   return   max  (  $res     0  );   }   // Driver Code   $arr   =   array  (  -  1     -  2     -  3     4  );   $n   =   count  (  $arr  );   echo   max_product  (  $arr     $n  );   // This code is contributed by anuj_67.   ?>   
JavaScript
    <  script  >      // JavaScript program to find maximum product      // subarray          // Function for maximum product      function     max_product  (  arr       n  )      {          // Initialize maximum products in       // forward and backward directions      let     max_fwd     =     Number  .  MIN_VALUE           max_bkd     =     Number  .  MIN_VALUE  ;          // Initialize current product      let     max_till_now     =     1  ;          // max_fwd for maximum contiguous       // product in forward direction      // max_bkd for maximum contiguous       // product in backward direction      // iterating within forward       // direction in array      for     (  let     i     =     0  ;     i      <     n  ;     i  ++  )      {          // if arr[i]==0 it is breaking       // condition for contiguous subarray      max_till_now     =     max_till_now     *     arr  [  i  ];          if     (  max_till_now     ==     0  )      {      max_till_now     =     1  ;      continue  ;      }          // update max_fwd      if     (  max_fwd      <     max_till_now  )         max_fwd     =     max_till_now  ;      }          max_till_now     =     1  ;          // iterating within backward       // direction in array      for     (  let     i     =     n     -     1  ;     i     >=     0  ;     i  --  )      {      max_till_now     =     max_till_now     *     arr  [  i  ];      if     (  max_till_now     ==     0  )      {      max_till_now     =     1  ;      continue  ;      }          // update max_bkd      if     (  max_bkd      <     max_till_now  )      max_bkd     =     max_till_now  ;      }          // return max of max_fwd and max_bkd      let     res     =     Math  .  max  (  max_fwd       max_bkd  );          // Product should not be negative.      // (Product of an empty subarray is      // considered as 0)      return     Math  .  max  (  res       0  );      }          let     arr     =     [  -  1       -  2       -  3       4  ];      let     n     =     arr  .  length  ;      document  .  write  (  max_product  (  arr       n  )     );        <  /script>   

Izvade
24  

Laika sarežģītība: O(n) 
Palīgtelpa: O(1)

Ņemiet vērā, ka iepriekšminētajam risinājumam ir nepieciešamas divas masīva šķērsošanas, kamēr iepriekšējais risinājums nepieciešama tikai viena šķērsošana.