Minimize division by 2 to make an Array strictly increasing
Last Updated :
10 Feb, 2023
Given an array nums[] of size N, the task is to find the minimum number of operations required to modify the array such that array elements are in strictly increasing order (A[i] < A[i+1]) where in each operation we can choose any element and perform nums[i] = [ nums[i] / 2] (where [x] represents the floor value of integer x).
Examples:
Input nums[] = {2, 8, 7, 5}
Output: 4
Explanation: Perform 1 operation on nums[0], 2 operations on nums[1], and 1 operation on nums[2].
Input: nums[] = {5, 3, 2, 1}
Output: -1
Explanation: It is impossible to obtain a strictly increasing sequence. Thus, return -1
Approach: The problem can be solved based on the following idea:
Idea is to start iterating from the second last element in the reverse direction and find if nums[i] ? nums[i+1] at any point we now can try to make nums[i] smaller than nums[i+1] by dividing the nums[i] by 2 until nums[i] becomes smaller than nums[i+1] and simultaneously can increase the count to keep record of operation done so far.
Follow the steps mentioned below to implement the idea:
- Initialize count = 0.
- Start iterating from the second last element in the reverse direction
- If nums[i+1] = 0, break and return -1 as this is not possible to make the array strictly increasing.
- As long as nums[i] ? nums[i+1] divide nums[i] by 2 and increment count.
- Return count as the required answer.
Below is the implementation of the above approach.
C++
#include <bits/stdc++.h>
using namespace std;
int minOperation(vector< int >& nums, int n)
{
bool flag = false ;
int count = 0;
for ( int i = n - 2; i >= 0; i--) {
if (nums[i + 1] == 0) {
flag = true ;
break ;
}
while (nums[i] >= nums[i + 1]) {
count++;
nums[i] /= 2;
}
}
if (flag == true )
return -1;
return count;
}
int main()
{
vector< int > nums = { 2, 8, 7, 5 };
int N = nums.size();
cout << minOperation(nums, N);
return 0;
}
|
Java
import java.util.*;
import java.io.*;
class GFG {
public static int minOperation( int [] nums, int n) {
int flag = 0 ;
int count = 0 ;
for ( int i = n- 2 ; i >= 0 ; i--) {
if (nums[i+ 1 ] == 0 ) {
flag = 1 ;
break ;
}
while (nums[i] >= nums[i+ 1 ]) {
count++;
nums[i] /= 2 ;
}
}
if (flag == 1 )
return - 1 ;
return count;
}
public static void main(String[] args) {
int [] nums = { 2 , 8 , 7 , 5 };
int N = nums.length;
System.out.println(minOperation(nums, N));
}
}
|
C#
using System;
using System.Collections.Generic;
class GFG {
static int minOperation(List< int > nums, int n)
{
bool flag = false ;
int count = 0;
for ( int i = n - 2; i >= 0; i--) {
if (nums[i + 1] == 0) {
flag = true ;
break ;
}
while (nums[i] >= nums[i + 1]) {
count++;
nums[i] /= 2;
}
}
if (flag == true )
return -1;
return count;
}
public static void Main()
{
List< int > nums = new List< int >{ 2, 8, 7, 5 };
int N = nums.Count;
Console.Write(minOperation(nums, N));
}
}
|
Javascript
function minOperation(nums, n)
{
let flag = false
let count = 0
for (let i = n - 2; i >= 0; i--) {
if (nums[i + 1] == 0) {
flag = true
break
}
while (nums[i] >= nums[i + 1]) {
count++
nums[i] /= 2
}
}
if (flag == true )
return -1
return count
}
let nums = [2, 8, 7, 5 ]
let N = nums.length
console.log(minOperation(nums, N))
|
Python3
def minOperation(nums):
n = len (nums)
flag = False
count = 0
for i in range (n - 2 , - 1 , - 1 ):
if nums[i + 1 ] = = 0 :
flag = True
break
while nums[i] > = nums[i + 1 ]:
count + = 1
nums[i] = nums[i] / / 2
if flag:
return - 1
return count
if __name__ = = '__main__' :
nums = [ 2 , 8 , 7 , 5 ]
print (minOperation(nums))
|
Time Complexity: O(N)
Auxiliary Space: O(1)
Related Articles:
Share your thoughts in the comments
Please Login to comment...