Open In App

Check if Array can be made strictly increasing by merging three consecutive elements M times

Last Updated : 20 Mar, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

Given an array arr[] of length N and an integer M, the task is to determine if a strictly increasing sequence can be formed by merging three consecutive elements exactly M times.

Note: Merging three elements means removing all three of them and inserting a single element having value same as the sum of the three at the same position.

Examples:

Input: arr = {10, 24, 26, 2, 32, 36}, M = 2
Output: True
Explanation: 1st Operation – Merge arr[3], arr[4] and arr[5] to get arr[4] = 70,  
Delete arr[5] and arr[6], arr = {10, 24, 26, 70}
2nd Operation – Merge arr[0], arr[1] and arr[2] to get arr[0] = 60
Delete arr[1] and arr[2], arr = {60, 70}, which is a strictly increasing array.

Input: arr = {1, 2, 3}, M = 2
Output: False
Explanation: 1st Operation – Merge arr[0], arr[1] and arr[2] to get arr[0] = 6,  
Delete arr[1] and arr[2], arr = {6}
2nd Operation is not possible as there are not enough elements left.

Approach: 

This problem can be solved using greedy approach. Each time decreasing sequence is found, merge the following three elements in order to make the array increasing, remove two elements and decrease the array size. Keep on repeating this process to find whether array can be transformed into strictly increasing after all the M operations.

Follow the below steps to solve the given problem:

  • Traverse until i>0 and M>0 and the array is not empty.
  • For each position there are three choices:
    • If the arr[i]<arr[i-1] and i+2<arr.size() then perform arr[i]=arr[i]+arr[i+1]+arr[i+2] and delete arr[i+1] and arr[i+2] and call the function recursively with new array and M-1.
    • If the arr[i]<arr[i-1] and i>=2 then perform arr[i-2]=arr[i-2]+arr[i]+arr[i-1] and delete arr[i-1] and arr[i] and call the function recursively with new array and M-1.
    • If the arr[i]<arr[i-1] and i<2 then perform arr[i-1]=arr[i-1]+arr[i]+arr[i+1] and delete arr[i] and arr[i+1] and call the function recursively with new array and M-1.
  • If the array is strictly increasing and 2*M<size of array arr then return True else return False.

Below is the implementation of this approach:

C++14




// C++ code to implement the greedy approach
#include <bits/stdc++.h>
using namespace std;
 
// function to check whether array is strictly increasing or not
bool isIncreasing(vector<int>& arr)
{
    for (int i = 1; i < arr.size(); i++) {
        if (arr[i - 1] > arr[i])
            return false;
    }
    return true;
}
 
// function to check whether we can make
// given an array an increasing array
// in exact M operations
bool make_inc_seq(vector<int> arr, int M)
{
    vector<int> temp(arr);
    if (isIncreasing(arr) && 2 * M < arr.size())
        return 1;
    else if (!M || arr.size() < 3)
        return 0;
    bool ans1 = 0, ans2 = 0, ans3 = 0;
 
    for (int i = arr.size() - 1; i > 0; i--) {
        if (arr[i] < arr[i - 1]) {
            if (arr.size() > i + 2 && i >= 0) {
                arr.clear();
                arr = temp;
                arr[i] = arr[i] + arr[i + 1] + arr[i + 2];
                arr.erase(arr.begin() + i + 1);
                arr.erase(arr.begin() + i + 1);
                ans1 = make_inc_seq(arr, M - 1);
            }
            if (i >= 2 && i < arr.size()) {
                arr.clear();
                arr = temp;
                arr[i - 2] = arr[i - 2] + arr[i - 1] + arr[i];
                arr.erase(arr.begin() + i);
                arr.erase(arr.begin() + i - 1);
                ans2 = make_inc_seq(arr, M - 1);
            }
            if (i >= 1 && i + 1 < arr.size()) {
                arr.clear();
                arr = temp;
                arr[i - 1] = arr[i - 1] + arr[i] + arr[i + 1];
                arr.erase(arr.begin() + i);
                arr.erase(arr.begin() + i);
                ans3 = make_inc_seq(arr, M - 1);
            }
        }
    }
 
    return ans1 || ans2 || ans3;
}
 
// Driver's code
int main()
{
    vector<int> arr = { 10, 24, 26, 2, 32, 36 };
    int M = 2;
    if (make_inc_seq(arr, M))
        cout << "True";
    else
        cout << "False";
    return 0;
}
// this code is contributed by prophet1999


Java




// Java code to implement the greedy approach
import java.util.*;
 
public class GFG
{
 
  // function to check whether array is strictly
  // increasing or not
  public static boolean isIncreasing(List<Integer> arr)
  {
    for (int i = 1; i < arr.size(); i++) {
      if (arr.get(i - 1) > arr.get(i))
        return false;
    }
    return true;
  }
 
  // function to check whether we can make
  // given an array an increasing array
  // in exact M operations
  public static boolean makeIncSeq(List<Integer> arr,
                                   int M)
  {
    List<Integer> temp = new ArrayList<>(arr);
    if (isIncreasing(arr) && 2 * M < arr.size())
      return true;
    else if (M == 0 || arr.size() < 3)
      return false;
    boolean ans1 = false, ans2 = false, ans3 = false;
 
    for (int i = arr.size() - 1; i > 0; i--) {
      if (arr.get(i) < arr.get(i - 1)) {
        if (arr.size() > i + 2 && i >= 0) {
          arr = new ArrayList<>(temp);
          arr.set(i, arr.get(i) + arr.get(i + 1)
                  + arr.get(i + 2));
          arr.remove(i + 1);
          arr.remove(i + 1);
          ans1 = makeIncSeq(arr, M - 1);
        }
        if (i >= 2 && i < arr.size()) {
          arr = new ArrayList<>(temp);
          arr.set(i - 2, arr.get(i - 2)
                  + arr.get(i - 1)
                  + arr.get(i));
          arr.remove(i);
          arr.remove(i - 1);
          ans2 = makeIncSeq(arr, M - 1);
        }
        if (i >= 1 && i + 1 < arr.size()) {
          arr = new ArrayList<>(temp);
          arr.set(i - 1, arr.get(i - 1)
                  + arr.get(i)
                  + arr.get(i + 1));
          arr.remove(i);
          arr.remove(i);
          ans3 = makeIncSeq(arr, M - 1);
        }
      }
    }
 
    return ans1 || ans2 || ans3;
  }
 
  // Driver's code
  public static void main(String[] args)
  {
    List<Integer> a// Java code to implement the greedy approach
import java.util.*;
 
public class GFG
{
 
  // function to check whether array is strictly
  // increasing or not
  public static boolean isIncreasing(List<Integer> arr)
  {
    for (int i = 1; i < arr.size(); i++) {
      if (arr.get(i - 1) > arr.get(i))
        return false;
    }
    return true;
  }
 
  // function to check whether we can make
  // given an array an increasing array
  // in exact M operations
  public static boolean makeIncSeq(List<Integer> arr,
                                   int M)
  {
    List<Integer> temp = new ArrayList<>(arr);
    if (isIncreasing(arr) && 2 * M < arr.size())
      return true;
    else if (M == 0 || arr.size() < 3)
      return false;
    boolean ans1 = false, ans2 = false, ans3 = false;
 
    for (int i = arr.size() - 1; i > 0; i--) {
      if (arr.get(i) < arr.get(i - 1)) {
        if (arr.size() > i + 2 && i >= 0) {
          arr = new ArrayList<>(temp);
          arr.set(i, arr.get(i) + arr.get(i + 1)
                  + arr.get(i + 2));
          arr.remove(i + 1);
          arr.remove(i + 1);
          ans1 = makeIncSeq(arr, M - 1);
        }
        if (i >= 2 && i < arr.size()) {
          arr = new ArrayList<>(temp);
          arr.set(i - 2, arr.get(i - 2)
                  + arr.get(i - 1)
                  + arr.get(i));
          arr.remove(i);
          arr.remove(i - 1);
          ans2 = makeIncSeq(arr, M - 1);
        }
        if (i >= 1 && i + 1 < arr.size()) {
          arr = new ArrayList<>(temp);
          arr.set(i - 1, arr.get(i - 1)
                  + arr.get(i)
                  + arr.get(i + 1));
          arr.remove(i);
          arr.remove(i);
          ans3 = makeIncSeq(arr, M - 1);
        }
      }
    }
 
    return ans1 || ans2 || ans3;
  }
 
  // Driver's code
  public static void main(String[] args)
  {
    List<Integer> arr = new ArrayList<>(
      Arrays.asList(10, 24, 26, 2, 32, 36));
    int M = 2;
    if (makeIncSeq(arr, M))
      System.out.println("True");
    else
      System.out.println("False");
  }
}rr = new ArrayList<>(
      Arrays.asList(10, 24, 26, 2, 32, 36));
    int M = 2;
    if (makeIncSeq(arr, M))
      System.out.println("True");
    else
      System.out.println("False");
  }
}


Python3




# function to check whether array is strictly increasing or not
def isIncreasing(arr):
    for i in range(1, len(arr)):
        if arr[i - 1] > arr[i]:
            return False
    return True
 
# function to check whether we can make
# given an array an increasing array
# in exact M operations
def make_inc_seq(arr, M):
    temp = arr.copy()
    if isIncreasing(arr) and 2 * M < len(arr):
        return True
    elif M == 0 or len(arr) < 3:
        return False
    ans1, ans2, ans3 = False, False, False
 
    for i in range(len(arr) - 1, 0, -1):
        if arr[i] < arr[i - 1]:
            if len(arr) > i + 2 and i >= 0:
                arr = temp.copy()
                arr[i] += arr[i + 1] + arr[i + 2]
                arr.pop(i + 1)
                arr.pop(i + 1)
                ans1 = make_inc_seq(arr, M - 1)
            if i >= 2 and i < len(arr):
                arr = temp.copy()
                arr[i - 2] += arr[i - 1] + arr[i]
                arr.pop(i)
                arr.pop(i - 1)
                ans2 = make_inc_seq(arr, M - 1)
            if i >= 1 and i + 1 < len(arr):
                arr = temp.copy()
                arr[i - 1] += arr[i] + arr[i + 1]
                arr.pop(i)
                arr.pop(i)
                ans3 = make_inc_seq(arr, M - 1)
 
    return ans1 or ans2 or ans3
 
# Driver's code
arr = [10, 24, 26, 2, 32, 36]
M = 2
if make_inc_seq(arr, M):
    print("True")
else:
    print("False")


C#




// C# code to implement the greedy approach
 
using System;
using System.Collections.Generic;
 
public class Solution
{
 
  // function to check whether array is strictly increasing or not
  public static bool IsIncreasing(List<int> arr)
  {
    for (int i = 1; i < arr.Count; i++)
    {
      if (arr[i - 1] > arr[i])
      {
        return false;
      }
    }
    return true;
  }
 
  // function to check whether we can make
  // given an array an increasing array
  // in exact M operations
  public static bool MakeIncSeq(List<int> arr, int M)
  {
    List<int> temp = new List<int>(arr);
    if (IsIncreasing(arr) && 2 * M < arr.Count)
    {
      return true;
    }
    else if (M == 0 || arr.Count < 3)
    {
      return false;
    }
 
    bool ans1 = false, ans2 = false, ans3 = false;
 
    for (int i = arr.Count - 1; i > 0; i--)
    {
      if (arr[i] < arr[i - 1])
      {
        if (arr.Count > i + 2 && i >= 0)
        {
          arr = new List<int>(temp);
          arr[i] = arr[i] + arr[i + 1] + arr[i + 2];
          arr.RemoveAt(i + 1);
          arr.RemoveAt(i + 1);
          ans1 = MakeIncSeq(arr, M - 1);
        }
        if (i >= 2 && i < arr.Count)
        {
          arr = new List<int>(temp);
          arr[i - 2] = arr[i - 2] + arr[i - 1] + arr[i];
          arr.RemoveAt(i);
          arr.RemoveAt(i - 1);
          ans2 = MakeIncSeq(arr, M - 1);
        }
        if (i >= 1 && i + 1 < arr.Count)
        {
          arr = new List<int>(temp);
          arr[i - 1] = arr[i - 1] + arr[i] + arr[i + 1];
          arr.RemoveAt(i);
          arr.RemoveAt(i);
          ans3 = MakeIncSeq(arr, M - 1);
        }
      }
    }
 
    return ans1 || ans2 || ans3;
  }
 
  // Driver's code
  public static void Main()
  {
    List<int> arr = new List<int> { 10, 24, 26, 2, 32, 36 };
    int M = 2;
    if (MakeIncSeq(arr, M))
    {
      Console.WriteLine("True");
    }
    else
    {
      Console.WriteLine("False");
    }
  }
}


Javascript




// Javascript code to implement the greedy approach
 
// Function to check whether array is strictly increasing or not
function isIncreasing(arr)
{
    for (let i = 1; i < arr.length; i++) {
        if (arr[i - 1] > arr[i])
            return false;
    }
    return true;
}
 
// function to check whether we can make
// given an array an increasing array
// in exact M operations
function make_inc_seq(arr, M)
{
    let temp = arr.slice();
 
    if (isIncreasing(arr) == true && 2 * M < arr.length)
        return 1;
    else if (!M || arr.length < 3)
        return 0;
    let ans1 = 0, ans2 = 0, ans3 = 0;
 
    for (let i = arr.length - 1; i > 0; i--) {
        if (arr[i] < arr[i - 1]) {
            if (arr.length > i + 2 && i >= 0) {
                arr.splice(0, arr.length);
                arr = temp.slice();
                arr[i] = arr[i] + arr[i + 1] + arr[i + 2];
                arr.splice(i + 1, 1);
                arr.splice(i + 1, 1);
                ans1 = make_inc_seq(arr, M - 1);
            }
            if (i >= 2 && i < arr.length) {
                arr.splice(0, arr.length);
                arr = temp.slice();
                arr[i - 2] = arr[i - 2] + arr[i - 1] + arr[i];
                arr.splice(i, 1);
                arr.splice(i - 1, 1);
                ans2 = make_inc_seq(arr, M - 1);
            }
            if (i >= 1 && i + 1 < arr.length) {
                arr.splice(0, arr.length);
                arr = temp.slice();
                arr[i - 1] = arr[i - 1] + arr[i] + arr[i + 1];
                arr.splice(i, 1);
                arr.splice(i, 1);
                ans3 = make_inc_seq(arr, M - 1);
            }
        }
    }
 
    return ans1 || ans2 || ans3;
}
 
// Driver's code
 
let arr = [ 10, 24, 26, 2, 32, 36 ];
let M = 2;
if (make_inc_seq(arr, M))
    console.log("True");
else
    console.log("False");
 
// This code is contributed by Nidhi goel.


Output

True

Time Complexity: O(3min(M, N)*N)
Auxiliary Space: O(N)



Like Article
Suggest improvement
Previous
Next
Share your thoughts in the comments

Similar Reads