Given an array arr[], replace each element with the product of itself and its adjacent elements.
For index i:
- arr[i] = arr[i-1] * arr[i] * arr[i+1]
- Assume the previous of the first and the next of the last as 1.
Examples:
Input: arr[] = [2, 4, 5]
Output: [8, 40, 20]
Explanation:
For index i = 0, arr[0] = 1 * arr[0] * arr[1] = 1 * 2 * 4 = 8
For index i = 1, arr[1] = arr[0] * arr[1] * arr[2] = 2 * 4 * 5 = 40
For index i = 2, arr[2] = arr[1] * arr[2] * 1 = 4 * 5 * 1 = 20
Thus, the updated array becomes [8, 40, 20].
Input: arr[] = [2, 5, 7, 8, 3]
Output: [10, 70, 280, 168, 24]
Explanation:
For index i = 0, arr[0] = 1 * arr[0] * arr[1] = 1 * 2 * 5 = 10
For index i = 1, arr[1] = arr[0] * arr[1] * arr[2] = 2 * 5 * 7 = 70
For index i = 2, arr[2] = arr[1] * arr[2] * arr[3] = 5 * 7 * 8 = 280
For index i = 3, arr[3] = arr[2] * arr[3] * arr[4] = 7 * 8 * 3 = 168
For index i = 4, arr[4] = arr[3] * arr[4] * 1 = 8 * 3 * 1 = 24
Thus, the updated array becomes [10, 70, 280, 168, 24].
Table of Content
[Naive Approach] Using Auxiliary Array — O(n) Time, O(n) Space
The idea is to use a temporary array to store the updated values. This avoids losing the original values while computing the product for each element. After processing all elements, copy the temporary array back to the original array.
#include <iostream>
using namespace std;
void updateArray(vector<int> &arr)
{
int n = arr.size();
// Temporary array to store updated values
vector<int> temp(n);
for (int i = 0; i < n; i++)
{
// Previous adjacent element
int prev = (i == 0) ? 1 : arr[i - 1];
// Next adjacent element
int next = (i == n - 1) ? 1 : arr[i + 1];
// Store product of previous, current and next element
temp[i] = prev * arr[i] * next;
}
// Copy updated values back to original array
arr = temp;
}
int main()
{
vector<int> arr = {2, 4, 5};
updateArray(arr);
for (auto it : arr)
{
cout << it << " ";
}
return 0;
}
import java.util.*;
class Main {
static void updateArray(int[] arr) {
int n = arr.length;
// Temporary array to store updated values
int[] temp = new int[n];
for (int i = 0; i < n; i++) {
// Previous adjacent element
int prev = (i == 0) ? 1 : arr[i - 1];
// Next adjacent element
int next = (i == n - 1) ? 1 : arr[i + 1];
// Store product of previous, current and next element
temp[i] = prev * arr[i] * next;
}
// Copy updated values back to original array
for (int i = 0; i < n; i++) {
arr[i] = temp[i];
}
}
public static void main(String[] args) {
int[] arr = {2, 4, 5};
updateArray(arr);
for (int x : arr) {
System.out.print(x + " ");
}
}
}
def updateArray(arr):
n = len(arr)
# Temporary array to store updated values
temp = [0] * n
for i in range(n):
# Previous adjacent element
prev = 1 if i == 0 else arr[i - 1]
# Next adjacent element
next_ele = 1 if i == n - 1 else arr[i + 1]
# Store product of previous, current and next element
temp[i] = prev * arr[i] * next_ele
# Copy updated values back to original array
for i in range(n):
arr[i] = temp[i]
arr = [2, 4, 5]
updateArray(arr)
print(*arr)
using System;
class Program
{
static void UpdateArray(int[] arr)
{
int n = arr.Length;
// Temporary array to store updated values
int[] temp = new int[n];
for (int i = 0; i < n; i++)
{
// Previous adjacent element
int prev = (i == 0) ? 1 : arr[i - 1];
// Next adjacent element
int next = (i == n - 1) ? 1 : arr[i + 1];
// Store product of previous, current and next element
temp[i] = prev * arr[i] * next;
}
// Copy updated values back to original array
for (int i = 0; i < n; i++)
{
arr[i] = temp[i];
}
}
static void Main()
{
int[] arr = { 2, 4, 5 };
UpdateArray(arr);
foreach (int x in arr)
{
Console.Write(x + " ");
}
}
}
function updateArray(arr) {
let n = arr.length;
// Temporary array to store updated values
let temp = new Array(n);
for (let i = 0; i < n; i++) {
// Previous adjacent element
let prev = (i === 0) ? 1 : arr[i - 1];
// Next adjacent element
let next = (i === n - 1) ? 1 : arr[i + 1];
// Store product of previous, current and next element
temp[i] = prev * arr[i] * next;
}
// Copy updated values back to original array
for (let i = 0; i < n; i++) {
arr[i] = temp[i];
}
}
let arr = [2, 4, 5];
updateArray(arr);
console.log(...arr);
Output
8 40 20
Time Complexity: O(n)
Space Complexity: O(n)
[Expected Approach] In-Place using Previous Tracking — O(n) Time, O(1) Space
The idea is to update the array in-place while keeping track of the previous original element using a variable prev.
Working of Approach:
- Start with prev = 1
- For each index i, store the original value before updating it
- Use the next original directly from the array
- Replace arr[i] with prev * arr[i] * next
- Update prev with the original current value Let us understand with an example:
Let us understand with an example.
Input: arr[] = [2, 4, 5]
- Start traversal with prev = 1
- At i = 0, arr[0] = 1 * 2 * 4 = 8, prev = 2
- At i = 1, arr[1] = 2 * 4 * 5 = 40, prev = 4
- At i = 2, arr[2] = 4 * 5 * 1 = 20, prev = 5
Final array = [8, 40, 20]
#include <iostream>
using namespace std;
void updateArray(vector<int> &arr)
{
int n = arr.size();
// Stores previous original element
int prev = 1;
for (int i = 0; i < n; i++)
{
// Store current original value before updating
int curr = arr[i];
// Get next adjacent element
int next = (i == n - 1) ? 1 : arr[i + 1];
// Update current element
arr[i] = prev * curr * next;
// Update prev with original current value
prev = curr;
}
}
int main()
{
vector<int> arr = {2, 4, 5};
updateArray(arr);
for (auto it : arr)
{
cout << it << " ";
}
return 0;
}
import java.util.*;
class Main {
static void updateArray(int[] arr) {
int n = arr.length;
// Stores previous original element
int prev = 1;
for (int i = 0; i < n; i++) {
// Store current original value before updating
int curr = arr[i];
// Get next adjacent element
int next = (i == n - 1) ? 1 : arr[i + 1];
// Update current element
arr[i] = prev * curr * next;
// Update prev with original current value
prev = curr;
}
}
public static void main(String[] args) {
int[] arr = {2, 4, 5};
updateArray(arr);
for (int x : arr) {
System.out.print(x + " ");
}
}
}
def updateArray(arr):
n = len(arr)
# Stores previous original element
prev = 1
for i in range(n):
# Store current original value before updating
curr = arr[i]
# Get next adjacent element
next_ele = 1 if i == n - 1 else arr[i + 1]
# Update current element
arr[i] = prev * curr * next_ele
# Update prev with original current value
prev = curr
arr = [2, 4, 5]
updateArray(arr)
print(*arr)
using System;
class Program
{
static void UpdateArray(int[] arr)
{
int n = arr.Length;
// Stores previous original element
int prev = 1;
for (int i = 0; i < n; i++)
{
// Store current original value before updating
int curr = arr[i];
// Get next adjacent element
int next = (i == n - 1) ? 1 : arr[i + 1];
// Update current element
arr[i] = prev * curr * next;
// Update prev with original current value
prev = curr;
}
}
static void Main()
{
int[] arr = { 2, 4, 5 };
UpdateArray(arr);
foreach (int x in arr)
{
Console.Write(x + " ");
}
}
}
function updateArray(arr) {
let n = arr.length;
// Stores previous original element
let prev = 1;
for (let i = 0; i < n; i++) {
// Store current original value before updating
let curr = arr[i];
// Get next adjacent element
let next = (i === n - 1) ? 1 : arr[i + 1];
// Update current element
arr[i] = prev * curr * next;
// Update prev with original current value
prev = curr;
}
}
let arr = [2, 4, 5];
updateArray(arr);
console.log(...arr);
Output
8 40 20
Time Complexity: O(n)
Space Complexity: O(1)