Given a sorted array arr[] that may contain duplicate elements. The task is to find the index of the last occurrence of any duplicate element and return the index along with the value of that element. If no duplicate element is found, return [-1, -1].
Examples:
Input: arr[] = [1, 5, 5, 6, 6, 7]
Output: [4, 6]
Explanation: Last duplicate element is 6 having index 4.
Input: arr[] = [1, 2, 3, 4, 5]
Output: [-1, -1]
Explanation: No duplicate elements are present in the array.
Table of Content
[Naive Approach] Using Linear Scan from Left to Right - O(n) Time O(1) Space
The idea is to traverse the sorted array from left to right and compare every element with its next element. Since duplicates appear consecutively in a sorted array, whenever two adjacent elements are equal, store their index and value.
#include <iostream>
#include <vector>
using namespace std;
vector<int> dupLastIndex(vector<int> &arr)
{
vector<int> res = {-1, -1};
int n = arr.size();
// Traverse the array
for (int i = 0; i < n - 1; i++)
{
// If duplicate found
if (arr[i] == arr[i + 1])
{
res = {i + 1, arr[i]};
}
}
return res;
}
// Driver Code
int main()
{
vector<int> arr = {1, 5, 5, 6, 6, 7};
vector<int> res = dupLastIndex(arr);
cout << "[" << res[0] << ", " << res[1] << "]";
return 0;
}
import java.util.Arrays;
public class GfG {
public static int[] dupLastIndex(int[] arr)
{
int[] res = { -1, -1 };
int n = arr.length;
// Traverse the array
for (int i = 0; i < n - 1; i++) {
// If duplicate found
if (arr[i] == arr[i + 1]) {
res[0] = i + 1;
res[1] = arr[i];
}
}
return res;
}
public static void main(String[] args)
{
int[] arr = { 1, 5, 5, 6, 6, 7 };
int[] res = dupLastIndex(arr);
System.out.println(Arrays.toString(res));
}
}
def dupLastIndex(arr):
res = [-1, -1]
n = len(arr)
# Traverse the array
for i in range(n - 1):
# If duplicate found
if arr[i] == arr[i + 1]:
res = [i + 1, arr[i]]
return res
# Driver Code
if __name__ == "__main__":
arr = [1, 5, 5, 6, 6, 7]
res = dupLastIndex(arr)
print(res)
using System;
public class GfG {
public static int[] dupLastIndex(int[] arr)
{
int[] res = { -1, -1 };
int n = arr.Length;
// Traverse the array
for (int i = 0; i < n - 1; i++) {
// If duplicate found
if (arr[i] == arr[i + 1]) {
res[0] = i + 1;
res[1] = arr[i];
}
}
return res;
}
public static void Main()
{
int[] arr = { 1, 5, 5, 6, 6, 7 };
int[] res = dupLastIndex(arr);
Console.WriteLine("[" + res[0] + ", " + res[1]
+ "]");
}
}
function dupLastIndex(arr)
{
let res = [ -1, -1 ];
let n = arr.length;
// Traverse the array
for (let i = 0; i < n - 1; i++) {
// If duplicate found
if (arr[i] === arr[i + 1]) {
res = [ i + 1, arr[i] ];
}
}
return res;
}
// Driver Code
let arr = [ 1, 5, 5, 6, 6, 7 ];
let res = dupLastIndex(arr);
console.log(`[${res[0]}, ${res[1]}]`);
Output
[4, 6]
Time Complexity: O(n)
Auxiliary Space: O(1)
[Expected Approach] Using Linear Scan from Right to Left - O(n) Time O(1) Space
The idea is to traverse the sorted array from right to left and compare every element with its previous element. Since duplicate elements occur consecutively, the first duplicate pair found during this traversal will be the last duplicate.
Let us understand with example:
Input: arr[] = [1, 5, 5, 6, 6, 7]
- Start traversing the array from the end.
- At index 5, arr[5] = 7 and arr[4] = 6, so no duplicate is found.
- At index 4, arr[4] = 6 and arr[3] = 6, so a duplicate is found.
- Return {4, 6} as the index and value of the last duplicate element.
Output: [4, 6]
#include <iostream>
#include <vector>
using namespace std;
vector<int> dupLastIndex(vector<int> &arr)
{
int n = arr.size();
// Traverse from end
for (int i = n - 1; i > 0; i--)
{
// If duplicate found
if (arr[i] == arr[i - 1])
{
vector<int> res = {i, arr[i]};
return res;
}
}
return {-1, -1};
}
// Driver Code
int main()
{
vector<int> arr = {1, 5, 5, 6, 6, 7};
vector<int> res = dupLastIndex(arr);
cout << "[" << res[0] << ", " << res[1] << "]";
return 0;
}
import java.util.Arrays;
public class GfG {
public static int[] dupLastIndex(int[] arr)
{
int n = arr.length;
// Traverse from end
for (int i = n - 1; i > 0; i--) {
// If duplicate found
if (arr[i] == arr[i - 1]) {
return new int[] { i, arr[i] };
}
}
return new int[] { -1, -1 };
}
public static void main(String[] args)
{
int[] arr = { 1, 5, 5, 6, 6, 7 };
int[] res = dupLastIndex(arr);
System.out.println(Arrays.toString(res));
}
}
def dupLastIndex(arr):
n = len(arr)
# Traverse from end
for i in range(n - 1, 0, -1):
# If duplicate found
if arr[i] == arr[i - 1]:
return [i, arr[i]]
return [-1, -1]
# Driver Code
if __name__ == "__main__":
arr = [1, 5, 5, 6, 6, 7]
res = dupLastIndex(arr)
print(res)
using System;
using System.Collections.Generic;
public class GfG {
public static List<int> dupLastIndex(int[] arr)
{
int n = arr.Length;
// Traverse from end
for (int i = n - 1; i > 0; i--) {
// If duplicate found
if (arr[i] == arr[i - 1]) {
List<int> res = new List<int>{ i, arr[i] };
return res;
}
}
return new List<int>{ -1, -1 };
}
// Driver Code
public static void Main()
{
int[] arr = { 1, 5, 5, 6, 6, 7 };
List<int> res = dupLastIndex(arr);
Console.WriteLine("[" + res[0] + ", " + res[1]
+ "]");
}
}
function dupLastIndex(arr) {
let n = arr.length;
// Traverse from end
for (let i = n - 1; i > 0; i--) {
// If duplicate found
if (arr[i] === arr[i - 1]) {
return [i, arr[i]];
}
}
return [-1, -1];
}
// Driver Code
let arr = [1, 5, 5, 6, 6, 7];
let res = dupLastIndex(arr);
console.log(`[${res[0]}, ${res[1]}]`);
Output
[4, 6]
Time Complexity: O(n)
Auxiliary Space: O(1)