VOOZH about

URL: https://www.geeksforgeeks.org/dsa/maximum-length-bitonic-subarray/

⇱ Maximum Length Bitonic Subarray - GeeksforGeeks


  • Courses
  • Tutorials
  • Interview Prep

Maximum Length Bitonic Subarray

Last Updated : 27 May, 2026

Given an array arr[] of size n containing positive integers, return the maximum length of the bitonic subarray.

A subarray arr[i...j] is considered bitonic if its elements first monotonically increase, and then monotonically decrease. Formally, there exists and index k (where i <= k <= j) such that:

  • arr[i] <= arr[i+1] <= . . . <= arr[k] 
  • arr[k] >= arr[k+1] >= . . . >= arr[j]

Examples

Input: arr[] = [12, 4, 78, 90, 45, 23]
Output: 5
Explanation: The longest bitonic subarray is [4, 78, 90, 45, 23]. It starts increasing at 4, peaks at 90, and decreases to 23, giving a length of 5.

Input: arr[] = [10, 20, 30, 40] 
Output: 4
Explanation: The array [10, 20, 30, 40] is strictly increasing with no decreasing part, so the longest bitonic subarray is the entire array itself, giving a length of 4.

[Naive Approach] Using Nested Loops - O(n3) time and O(1) space

We check all possible subarrays, trying each index as a peak. If a subarray follows the bitonic pattern, we update the longest length found.


Output
5

[Expected Approach] Precompute Increasing Decreasing - O(n) time and O(n) space

For solving this problem we can imagine each number as the peak of a mountain. For every element, count how many consecutive numbers before it are rising (or flat) and how many after it are falling (or flat). Add these two counts and subtract one (to avoid counting the peak twice). The longest mountain found this way is answer.


Output
5

[Optimized Approach] Single Traversal - O(n) time and O(1) space

The idea is to find the longest bitonic subarray starting from each index arr[i]. From arr[i], the process first detects the end of the ascent (increasing sequence), then the descent (decreasing sequence). To handle overlapping subarrays, we record the nextStart position when two equal values are encountered during the descent phase. If the length of the current bitonic subarray exceeds the previously recorded maxLen, we update it.

Implementation:

  • Initialize variables maxLen (defaults to 1), start (beginning of the current sequence), nextStart (potential start for the next sequence), and an iterator j = 0.
  • Loop through the array as long as j < n-1.
  • Using a while loop, keep incrementing j as long as the sequence is non-decreasing (arr[j] <= arr[j+1]). This finds the peak.
  • Using another while loop, keep incrementing j as long as the sequence is non-increasing (arr[j] >= arr[j+1]).
  • Inside the descent loop, whenever you encounter a strictly decreasing step (arr[j] > arr[j+1]), update nextStart = j+1. This safely marks where the next potential sequence should start.
  • Calculate the length of the just-completed bitonic sequence (j - start +1) and update maxLen if it is strictly greater.
  • Update start = nextStart to prepare for the next iteration of the main loop.
  • Once the array is fully traversed, return maxLen.

Example:

arr[]:[12, 4, 78, 90, 45, 23] Initial State: maxLen = 1, start = 0, nextStart = 0, j= 0

  • Iteration 1: start = 0 , j = 0→ Ascent skipped (12 > 4) → Descent advances j to 1 (12 > 4) and sets nextStart = 1 → maxLen = max(1,1-0+1) =2 → start=1.
  • Iteration 2: start = 1, j = 1 → Ascent advances j to 3 (4 < 78 < 90) → Descent advances j to 5 (90 > 45 > 23), updating nextStart = 5 → maxLen = max(2,5-1+1) → start = 5.
  • Loop Terminates: Condition j < 5 is now false. Function returns 5.

Output
5


Comment
Article Tags:
Article Tags: