Given an array arr[] of size n representing the heights of pillars on a track, determine whether the track is valid.
A track is valid if:
- The middle pillar has height exactly 1.
- The number of pillars on both sides of the middle pillar are equal, and corresponding pillars on each side have identical heights.
- The difference between heights of consecutive pillars is constant and non-zero.
Return true if the track is valid, otherwise return false.
Examples:
Input: arr[] = [3, 2, 1, 2, 3]
Output: true
Explanation: Middle pillar is 1, both sides are [3, 2] and [2, 3] which are mirrors of each other, and the constant height difference is 1.Input: arr[] = [3, 2, 1, 2, 4]
Output: false
Explanation: The sides [3, 2] and [2, 4] are not mirrors of each other.
Table of Content
[Naive Approach] Check Mirror Property and Constant Difference Separately - O(n) Time and O(1) Space
The idea is to separately check the mirror property and the constant non-zero difference between consecutive pillars.
Working of Approach:
- Check whether the array length is odd and the middle element is 1.
- Traverse the left half and compare each element with its corresponding element on the right half.
- Compute the difference between the first two consecutive elements.
- Traverse the array again and verify that every consecutive difference is equal to the first difference and is non-zero.
- If all conditions are satisfied, return true; otherwise, return false.
#include <bits/stdc++.h>
using namespace std;
bool validTrack(vector<int> &arr)
{
int n = arr.size();
// Track must have odd number of pillars
if (n % 2 == 0)
return false;
int mid = n / 2;
// Middle pillar must be 1
if (arr[mid] != 1)
return false;
// Check mirror property
for (int i = 0; i < mid; i++)
{
if (arr[i] != arr[n - 1 - i])
return false;
}
// Check constant difference on the left half
int leftDiff = arr[0] - arr[1];
if (leftDiff == 0)
return false;
for (int i = 0; i < mid; i++)
{
if (arr[i] - arr[i + 1] != leftDiff)
return false;
}
// Check constant difference on the right half
int rightDiff = arr[mid + 1] - arr[mid];
if (rightDiff == 0)
return false;
for (int i = mid; i < n - 1; i++)
{
if (arr[i + 1] - arr[i] != rightDiff)
return false;
}
return true;
}
int main()
{
vector<int> arr = {3, 2, 1, 2, 3};
if (validTrack(arr))
cout << "true";
else
cout << "false";
return 0;
}
import java.util.Arrays;
public class GFG {
public static boolean validTrack(int[] arr)
{
int n = arr.length;
// Track must have odd number of pillars
if (n % 2 == 0)
return false;
int mid = n / 2;
// Middle pillar must be 1
if (arr[mid] != 1)
return false;
// Check mirror property
for (int i = 0; i < mid; i++) {
if (arr[i] != arr[n - 1 - i])
return false;
}
// Check constant difference on the left half
int leftDiff = arr[0] - arr[1];
if (leftDiff == 0)
return false;
for (int i = 0; i < mid; i++) {
if (arr[i] - arr[i + 1] != leftDiff)
return false;
}
// Check constant difference on the right half
int rightDiff = arr[mid + 1] - arr[mid];
if (rightDiff == 0)
return false;
for (int i = mid; i < n - 1; i++) {
if (arr[i + 1] - arr[i] != rightDiff)
return false;
}
return true;
}
public static void main(String[] args)
{
int[] arr = { 3, 2, 1, 2, 3 };
if (validTrack(arr))
System.out.println("true");
else
System.out.println("false");
}
}
def validTrack(arr):
n = len(arr)
# Track must have odd number of pillars
if n % 2 == 0:
return False
mid = n // 2
# Middle pillar must be 1
if arr[mid] != 1:
return False
# Check mirror property
for i in range(mid):
if arr[i] != arr[n - 1 - i]:
return False
# Check constant difference on the left half
leftDiff = arr[0] - arr[1]
if leftDiff == 0:
return False
for i in range(mid):
if arr[i] - arr[i + 1] != leftDiff:
return False
# Check constant difference on the right half
rightDiff = arr[mid + 1] - arr[mid]
if rightDiff == 0:
return False
for i in range(mid, n - 1):
if arr[i + 1] - arr[i] != rightDiff:
return False
return True
if __name__ == '__main__':
arr = [3, 2, 1, 2, 3]
if validTrack(arr):
print('true')
else:
print('false')
using System;
public class GFG {
public static bool validTrack(int[] arr)
{
int n = arr.Length;
// Track must have odd number of pillars
if (n % 2 == 0)
return false;
int mid = n / 2;
// Middle pillar must be 1
if (arr[mid] != 1)
return false;
// Check mirror property
for (int i = 0; i < mid; i++) {
if (arr[i] != arr[n - 1 - i])
return false;
}
// Check constant difference on the left half
int leftDiff = arr[0] - arr[1];
if (leftDiff == 0)
return false;
for (int i = 0; i < mid; i++) {
if (arr[i] - arr[i + 1] != leftDiff)
return false;
}
// Check constant difference on the right half
int rightDiff = arr[mid + 1] - arr[mid];
if (rightDiff == 0)
return false;
for (int i = mid; i < n - 1; i++) {
if (arr[i + 1] - arr[i] != rightDiff)
return false;
}
return true;
}
public static void Main()
{
int[] arr = { 3, 2, 1, 2, 3 };
if (validTrack(arr))
Console.WriteLine("true");
else
Console.WriteLine("false");
}
}
function validTrack(arr)
{
let n = arr.length;
// Track must have odd number of pillars
if (n % 2 === 0)
return false;
let mid = Math.floor(n / 2);
// Middle pillar must be 1
if (arr[mid] !== 1)
return false;
// Check mirror property
for (let i = 0; i < mid; i++) {
if (arr[i] !== arr[n - 1 - i])
return false;
}
// Check constant difference on the left half
let leftDiff = arr[0] - arr[1];
if (leftDiff === 0)
return false;
for (let i = 0; i < mid; i++) {
if (arr[i] - arr[i + 1] !== leftDiff)
return false;
}
// Check constant difference on the right half
let rightDiff = arr[mid + 1] - arr[mid];
if (rightDiff === 0)
return false;
for (let i = mid; i < n - 1; i++) {
if (arr[i + 1] - arr[i] !== rightDiff)
return false;
}
return true;
}
// Driver Code
let arr = [ 3, 2, 1, 2, 3 ];
if (validTrack(arr))
console.log("true");
else
console.log("false");
Output
true
[Expected Approach] Single Traversal Using Constant Difference - O(n) Time and O(1) Space
The idea is to use the difference between the first two pillars and verify the required pattern on both sides of the middle pillar in a single traversal. If both halves follow the same constant difference in opposite directions, the track is valid.
Working of Approach:
- Check whether the array size is odd and the middle pillar has height 1.
- Compute the constant difference k using the first two pillars.
- Ensure that k is non-zero.
- Traverse the array once and verify the left half decreases by k while the right half increases by k.
- If every comparison succeeds, return true; otherwise, return false.
Let us understand with an example:
Input: arr[] = [3, 2, 1, 2, 3]
- The array has an odd number of elements, and the middle pillar is 1, so the basic conditions are satisfied.
- Compute the constant difference: k = 3 - 2 = 1.
- Before the middle, each pillar is exactly 1 greater than the next: 3 = 2 + 1, 2 = 1 + 1.
- After the middle, each pillar is exactly 1 smaller than the next: 1 = 2 - 1, 2 = 3 - 1.
- Since all checks are satisfied, the function returns true.
#include <bits/stdc++.h>
using namespace std;
bool validTrack(vector<int> &arr)
{
int n = arr.size();
// If the array size is even or the middle element is not 1, return false
if (n % 2 == 0 || arr[n / 2] != 1)
{
return false;
}
// Calculating the difference between the first two elements
int k = arr[0] - arr[1];
// If the difference is 0, the pattern is invalid
if (k == 0)
{
return false;
}
// Checking the pattern in the array
for (int i = 0; i < n - 1; i++)
{
if (i < n / 2)
{
// Check the pattern before the middle element
if (arr[i] != arr[i + 1] + k)
{
return false;
}
}
else
{
// Check the pattern after the middle element
if (arr[i] != arr[i + 1] - k)
{
return false;
}
}
}
// If all checks pass, return true
return true;
}
int main()
{
vector<int> arr = {3, 2, 1, 2, 3};
if (validTrack(arr))
cout << "true";
else
cout << "false";
return 0;
}
import java.util.Arrays;
public class GFG {
public static boolean validTrack(int[] arr)
{
int n = arr.length;
// If the array size is even or the middle element
// is not 1, return false
if (n % 2 == 0 || arr[n / 2] != 1) {
return false;
}
// Calculating the difference between the first two
// elements
int k = arr[0] - arr[1];
// If the difference is 0, the pattern is invalid
if (k == 0) {
return false;
}
// Checking the pattern in the array
for (int i = 0; i < n - 1; i++) {
if (i < n / 2) {
// Check the pattern before the middle
// element
if (arr[i] != arr[i + 1] + k) {
return false;
}
}
else {
// Check the pattern after the middle
// element
if (arr[i] != arr[i + 1] - k) {
return false;
}
}
}
// If all checks pass, return true
return true;
}
public static void main(String[] args)
{
int[] arr = { 3, 2, 1, 2, 3 };
if (validTrack(arr))
System.out.println("true");
else
System.out.println("false");
}
}
def validTrack(arr):
n = len(arr)
# If the array size is even or the middle element is not 1, return false
if n % 2 == 0 or arr[n // 2] != 1:
return False
# Calculating the difference between the first two elements
k = arr[0] - arr[1]
# If the difference is 0, the pattern is invalid
if k == 0:
return False
# Checking the pattern in the array
for i in range(n - 1):
if i < n // 2:
# Check the pattern before the middle element
if arr[i] != arr[i + 1] + k:
return False
else:
# Check the pattern after the middle element
if arr[i] != arr[i + 1] - k:
return False
# If all checks pass, return true
return True
if __name__ == '__main__':
arr = [3, 2, 1, 2, 3]
if validTrack(arr):
print('true')
else:
print('false')
using System;
public class GFG {
public static bool validTrack(int[] arr)
{
int n = arr.Length;
// If the array size is even or the middle element
// is not 1, return false
if (n % 2 == 0 || arr[n / 2] != 1) {
return false;
}
// Calculating the difference between the first two
// elements
int k = arr[0] - arr[1];
// If the difference is 0, the pattern is invalid
if (k == 0) {
return false;
}
// Checking the pattern in the array
for (int i = 0; i < n - 1; i++) {
if (i < n / 2) {
// Check the pattern before the middle
// element
if (arr[i] != arr[i + 1] + k) {
return false;
}
}
else {
// Check the pattern after the middle
// element
if (arr[i] != arr[i + 1] - k) {
return false;
}
}
}
// If all checks pass, return true
return true;
}
public static void Main()
{
int[] arr = { 3, 2, 1, 2, 3 };
if (validTrack(arr))
Console.WriteLine("true");
else
Console.WriteLine("false");
}
}
function validTrack(arr)
{
let n = arr.length;
// If the array size is even or the middle element is
// not 1, return false
if (n % 2 === 0 || arr[Math.floor(n / 2)] !== 1) {
return false;
}
// Calculating the difference between the first two
// elements
let k = arr[0] - arr[1];
// If the difference is 0, the pattern is invalid
if (k === 0) {
return false;
}
// Checking the pattern in the array
for (let i = 0; i < n - 1; i++) {
if (i < Math.floor(n / 2)) {
// Check the pattern before the middle element
if (arr[i] !== arr[i + 1] + k) {
return false;
}
}
else {
// Check the pattern after the middle element
if (arr[i] !== arr[i + 1] - k) {
return false;
}
}
}
// If all checks pass, return true
return true;
}
// Driver Code
let arr = [ 3, 2, 1, 2, 3 ];
if (validTrack(arr)) {
console.log("true");
}
else {
console.log("false");
}
Output
true