Given an array arr[] of integers, find the longest contiguous subarray in which each element is strictly greater than the one before it. If multiple subarrays have the same maximum length, return the first one.
Examples:
Input: arr[] = [5, 6, 3, 5, 7, 8, 9, 1, 2]
Output: [3, 5, 7, 8, 9]
Explanation: here the subarray arr[2:6] = [3, 5, 7, 8, 9] is the longest subarray to follow a strictly increasing order.Input: arr[] = [12, 13, 1, 5, 4, 7, 8, 10, 10, 11]
Output: [4, 7, 8, 10]
Explanation: here the subarray arr[4:7] = [4, 7, 8, 10] is the longest subarray to follow a strictly increasing order.
Table of Content
[Naive Approach] Using Nested Loops - O(n^2) Time O(1) Space
The Idea is to start from every index and extend forward while the sequence is increasing. Track the longest one.
#include <bits/stdc++.h>
using namespace std;
// Naive approach for Longest increasing subarray
vector<int> longIncSubArr(vector<int> &arr)
{
int n = arr.size();
int maxLen = 1;
int startIndex = 0;
// Try every starting point
for (int i = 0; i < n; i++)
{
int len = 1;
// Extend subarray from i
for (int j = i + 1; j < n; j++)
{
if (arr[j] > arr[j - 1])
{
len++;
}
else
{
break;
}
}
// Update best result
if (len > maxLen)
{
maxLen = len;
startIndex = i;
}
}
// Build result subarray
vector<int> result;
for (int i = startIndex; i < startIndex + maxLen; i++)
{
result.push_back(arr[i]);
}
return result;
}
// Driver Code
int main()
{
vector<int> arr = {5, 6, 3, 5, 7, 8, 9, 1, 2};
vector<int> result = longIncSubArr(arr);
for (int x : result)
{
cout << x << " ";
}
return 0;
}
#include <stdio.h>
// Naive approach for Longest increasing subarray
void longIncSubArr(int arr[], int n) {
int maxLen = 1;
int startIndex = 0;
// Try every starting point
for (int i = 0; i < n; i++)
{
int len = 1;
// Extend subarray from i
for (int j = i + 1; j < n; j++)
{
if (arr[j] > arr[j - 1])
{
len++;
}
else
{
break;
}
}
// Update best result
if (len > maxLen)
{
maxLen = len;
startIndex = i;
}
}
// Print result subarray
for (int i = startIndex; i < startIndex + maxLen; i++)
{
printf("%d ", arr[i]);
}
}
// Driver Code
int main() {
int arr[] = {5, 6, 3, 5, 7, 8, 9, 1, 2};
int n = sizeof(arr) / sizeof(arr[0]);
longIncSubArr(arr, n);
return 0;
}
import java.util.ArrayList;
// Naive approach for Longest increasing subarray
public class Main {
public static ArrayList<Integer> longIncSubArr(int[] arr) {
int n = arr.length;
int maxLen = 1;
int startIndex = 0;
for (int i = 0; i < n; i++) {
int len = 1;
for (int j = i + 1; j < n; j++) {
if (arr[j] > arr[j - 1]) {
len++;
} else {
break;
}
}
if (len > maxLen) {
maxLen = len;
startIndex = i;
}
}
ArrayList<Integer> result = new ArrayList<>();
for (int i = startIndex; i < startIndex + maxLen; i++) {
result.add(arr[i]);
}
return result;
}
public static void main(String[] args) {
int[] arr = {5, 6, 3, 5, 7, 8, 9, 1, 2};
ArrayList<Integer> result = longIncSubArr(arr);
for (int x : result) {
System.out.print(x + " ");
}
}
}
# Naive approach for Longest increasing subarray
def longIncSubArr(arr):
n = len(arr)
maxLen = 1
startIndex = 0
# Try every starting point
for i in range(n):
length = 1 # renamed (don't use 'len')
# Extend subarray from i
for j in range(i + 1, n):
if arr[j] > arr[j - 1]:
length += 1
else:
break
# Update best result
if length > maxLen:
maxLen = length
startIndex = i
return arr[startIndex:startIndex + maxLen]
# Driver Code
if __name__ == "__main__":
arr = [5, 6, 3, 5, 7, 8, 9, 1, 2]
result = longIncSubArr(arr)
for x in result:
print(x, end=' ')
using System;
using System.Collections.Generic;
// Naive approach for Longest increasing subarray
public class Program {
public static List<int> longIncSubArr(int[] arr) {
int n = arr.Length;
int maxLen = 1;
int startIndex = 0;
// Try every starting point
for (int i = 0; i < n; i++) {
int len = 1;
// Extend subarray from i
for (int j = i + 1; j < n; j++) {
if (arr[j] > arr[j - 1]) {
len++;
} else {
break;
}
}
// Update best result
if (len > maxLen) {
maxLen = len;
startIndex = i;
}
}
// Build result subarray
List<int> result = new List<int>();
for (int i = startIndex; i < startIndex + maxLen; i++) {
result.Add(arr[i]);
}
return result;
}
// Driver Code
public static void Main(string[] args) {
int[] arr = {5, 6, 3, 5, 7, 8, 9, 1, 2};
List<int> result = longIncSubArr(arr);
foreach (int x in result) {
Console.Write(x + " ");
}
}
}
// Naive approach for Longest increasing subarray
function longIncSubArr(arr) {
let n = arr.length;
let maxLen = 1;
let startIndex = 0;
// Try every starting point
for (let i = 0; i < n; i++) {
let len = 1;
// Extend subarray from i
for (let j = i + 1; j < n; j++) {
if (arr[j] > arr[j - 1]) {
len++;
} else {
break;
}
}
// Update best result
if (len > maxLen) {
maxLen = len;
startIndex = i;
}
}
// Build result subarray
let result = arr.slice(startIndex, startIndex + maxLen);
return result;
}
// Driver Code
let arr = [5, 6, 3, 5, 7, 8, 9, 1, 2];
let result = longIncSubArr(arr);
for (let x of result) {
console.log(x + ' ');
}
Output
3 5 7 8 9
[Expected Approach] Using Single Traversal - O(n) Time O(1) Space
The Idea is that Instead of checking all subarrays, we maintain a current increasing subarray. If the order breaks (arr[i] <= arr[i-1]), we start a new subarray (This is similar to Kadane's Algorithm). While traversing, we track the start index and maximum length of the best subarray, achieving an efficient O(n) solution.
Let us understand with an example:
Input: arr[] = [5, 6, 3, 5, 7, 8, 9, 1, 2]
Start traversing and maintain a current increasing subarray:
- Start from index 0 -> current = [5]
- At index 1 (6 > 5) -> current = [5, 6]
- At index 2 (3 <= 6) -> break, start new subarray -> current = [3]
- At index 3 (5 > 3) -> current = [3, 5]
- At index 4 (7 > 5) -> current = [3, 5, 7]
- At index 5 (8 > 7) -> current = [3, 5, 7, 8]
- At index 6 (9 > 8) -> current = [3, 5, 7, 8, 9]
- At index 7 (1 <= 9) -> break, start new subarray -> current = [1]
- At index 8 (2 > 1) -> current = [1, 2]
The longest subarray found is [3, 5, 7, 8, 9]
#include <iostream>
using namespace std;
// function to find longest increasing subarray
vector<int> longIncSubArr(vector<int> &arr)
{
int n = arr.size();
// start of current subarray and best subarray
int start = 0, bestStart = 0;
// maximum length found so far
int maxLen = 1;
for (int i = 1; i < n; i++)
{
// break in increasing order ? reset start
if (arr[i] <= arr[i - 1])
{
start = i;
}
// current subarray length
int currLen = i - start + 1;
// update best if longer subarray found
if (currLen > maxLen)
{
maxLen = currLen;
bestStart = start;
}
}
// return the longest subarray from bestStart to bestStart+maxLen
return vector<int>(arr.begin() + bestStart, arr.begin() + bestStart + maxLen);
}
// Driver Code
int main()
{
vector<int> arr = {5, 6, 3, 5, 7, 8, 9, 1, 2};
vector<int> result = longIncSubArr(arr);
for (int x : result)
{
cout << x << " ";
}
return 0;
}
#include <stdio.h>
#include <stdlib.h>
// function to find longest increasing subarray
int* longIncSubArr(int* arr, int n, int* resultSize)
{
int start = 0, bestStart = 0;
int maxLen = 1;
for (int i = 1; i < n; i++)
{
if (arr[i] <= arr[i - 1])
{
start = i;
}
int currLen = i - start + 1;
if (currLen > maxLen)
{
maxLen = currLen;
bestStart = start;
}
}
int* result = (int*)malloc(maxLen * sizeof(int));
for (int i = 0; i < maxLen; i++)
{
result[i] = arr[bestStart + i];
}
*resultSize = maxLen;
return result;
}
// Driver Code
int main()
{
int arr[] = {5, 6, 3, 5, 7, 8, 9, 1, 2};
int n = sizeof(arr) / sizeof(arr[0]);
int resultSize = 0;
int* result = longIncSubArr(arr, n, &resultSize);
for (int i = 0; i < resultSize; i++)
{
printf("%d ", result[i]);
}
free(result);
return 0;
}
import java.util.*;
public class Main {
public static ArrayList<Integer> longIncSubArr(int[] arr) {
int n = arr.length;
int start = 0, bestStart = 0;
int maxLen = 1;
for (int i = 1; i < n; i++) {
if (arr[i] <= arr[i - 1]) {
start = i;
}
int currLen = i - start + 1;
if (currLen > maxLen) {
maxLen = currLen;
bestStart = start;
}
}
ArrayList<Integer> result = new ArrayList<>();
for (int i = bestStart; i < bestStart + maxLen; i++) {
result.add(arr[i]);
}
return result;
}
public static void main(String[] args) {
int[] arr = {5, 6, 3, 5, 7, 8, 9, 1, 2};
ArrayList<Integer> result = longIncSubArr(arr);
for (int x : result) {
System.out.print(x + " ");
}
}
}
# function to find longest increasing subarray
def longIncSubArr(arr):
n = len(arr)
start = 0
bestStart = 0
maxLen = 1
for i in range(1, n):
if arr[i] <= arr[i - 1]:
start = i
currLen = i - start + 1
if currLen > maxLen:
maxLen = currLen
bestStart = start
return arr[bestStart:bestStart + maxLen]
# Driver Code
if __name__ == "__main__":
arr = [5, 6, 3, 5, 7, 8, 9, 1, 2]
result = longIncSubArr(arr)
print(" ".join(map(str, result)))
using System;
using System.Collections.Generic;
// function to find longest increasing subarray
public class Program
{
public static List<int> longIncSubArr(List<int> arr)
{
int n = arr.Count;
int start = 0, bestStart = 0;
int maxLen = 1;
for (int i = 1; i < n; i++)
{
if (arr[i] <= arr[i - 1])
{
start = i;
}
int currLen = i - start + 1;
if (currLen > maxLen)
{
maxLen = currLen;
bestStart = start;
}
}
return arr.GetRange(bestStart, maxLen);
}
public static void Main()
{
List<int> arr = new List<int> {5, 6, 3, 5, 7, 8, 9, 1, 2};
List<int> result = longIncSubArr(arr);
foreach (int x in result)
{
Console.Write(x + " ");
}
}
}
// function to find longest increasing subarray
function longIncSubArr(arr) {
let n = arr.length;
let start = 0, bestStart = 0;
let maxLen = 1;
for (let i = 1; i < n; i++) {
if (arr[i] <= arr[i - 1]) {
start = i;
}
let currLen = i - start + 1;
if (currLen > maxLen) {
maxLen = currLen;
bestStart = start;
}
}
return arr.slice(bestStart, bestStart + maxLen);
}
// Driver Code
let arr = [5, 6, 3, 5, 7, 8, 9, 1, 2];
let result = longIncSubArr(arr);
console.log(result.join(' '));
Output
3 5 7 8 9
Time Complexity: O(n)
Space Complexity: O(1)