Arrays Easy - Part I

I. Largest Element in the Array

Problem Statement

Given an array, we have to find the largest element in the array. (link)

Optimal Solution

We assume one element to be the maximum element, iterate through all the elements, and check if the assumed element is greater than the current element. If the current one is greater than the maximum assumed, then we update the maximum assumed to the current element and proceed further.

import java.util.* ;
import java.io.*; 

public class Solution {
    static int largestElement(int[] arr, int n) {
        int maxAns = arr[0];
        for(int i=0; i<n; i++) maxAns = Math.max(maxAns, arr[i]);
        return maxAns;
    }
}

II. Second Largest Number

Problem Statement

Given an array, find the second smallest and second largest element in the array. Print ‘-1’ if either of them doesn’t exist. (link)

Optimal Solution

The approach to finding the second largest or smallest element follows a similar logic. We initiate two variables, first_maximum and second_maximum, setting them to the minimum possible value using Integer.MIN_VALUE. Next, we iterate through the array. If the current element exceeds the current first maximum, we update the first maximum with the current element. Simultaneously, while updating the first maximum, we assign the previous maximum to the second maximum since there is a high likelihood that this value could be the second maximum. If the current element does not surpass the first maximum, we check whether it can surpass the second maximum. If it does, we update the second maximum accordingly.

public class Solution {
    public static int[] getSecondOrderElements(int n, int []a) {
        int firstMax = Integer.MIN_VALUE;
        int firstMin = Integer.MAX_VALUE;
        int secondMax = Integer.MIN_VALUE;
        int secondMin = Integer.MAX_VALUE;

        for(int element: a){
            if(element>firstMax){
                secondMax = firstMax;
                firstMax = element;
            } else if(firstMax> element && secondMax < element){
                secondMax = element;
            }

            if(element<firstMin){
                secondMin = firstMin;
                firstMin = element;
            } else if(firstMin<element && secondMin>element){
                secondMin = element;
            }
        }

        return new int[] {secondMax, secondMin};
    }
}

III. Check if the Array Is Sorted and Rotated

Problem Statement

Given an array nums, return true if the array was originally sorted in non-decreasing order, then rotated some number of positions (including zero). Otherwise, return false.

There may be duplicates in the original array.

Note: An array A rotated by x position results in an array B of the same length such that A[i] == B[(i+x) % A.length], where % is the modulo operation. (link)

Example:

Input: nums = [3,4,5,1,2]
Output: true
Explanation: [1,2,3,4,5] is the original sorted array.
You can rotate the array by x = 3 positions to begin on the the element of value 3: [3,4,5,1,2].

Optimal Solution

If an array is sorted, then nums[i] should always be less than nums[i+1]. In our case, for a rotated sorted array, at maximum, we can have one pair of elements that breaks this condition. If the number of breaks is more than 1, then the array is not sorted.

Example 1: nums = [4, 5, 1, 2, 3]

In this example, (5, 1) is the breaking pair, and we can only see one pair.

However, this logic can be disrupted for non-sorted arrays.

Example 2: nums = [3, 5, 1, 2, 4]

To address this issue, we can always compare the first and last elements if the number of breaks is 1. If it is a rotated sorted array, then the first element should always be greater than the last element.

Example 3: nums = [3, 5, 1, 4, 2]

Don't quickly jump and compare the first element with the last element. Here, 3 > 2, but the number of breaks is 2, involving pairs (5, 1) and (4, 2).

class Solution {
    public boolean check(int[] nums) {
        int noOfbreaks = 0;

        for(int i=0; i<nums.length-1; i++){
            if(nums[i]>nums[i+1]){
                noOfbreaks+=1;
            }

            if(noOfbreaks>1) return false;
        }

        if(noOfbreaks==1 && nums[0]<nums[nums.length-1]) return false;
        return true;
    }
}

IV. Remove Duplicates from the Sorted Array

Problem Statement

Given an integer array sorted in non-decreasing order, remove the duplicates in place such that each unique element appears only once. The relative order of the elements should be kept the same.

If there are k elements after removing the duplicates, then the first k elements of the array should hold the final result. It does not matter what you leave beyond the first k elements. (link)

Note: Return k after placing the final result in the first k slots of the array.

Optimal Solution

Approach 1 - A simple method involves creating a new array of the same size and copying the distinct elements into it. When inserting an element into this new array, it's necessary to verify that the last copied element is not identical to the current element. If they differ, insert the current element into the new array.

Begin by inserting the first element of the original array into the first element of the new array. Subsequently, copy the result back into the original array.

class Solution {
    public int removeDuplicates(int[] nums) {
        int dup[] = new int[nums.length];

        int index = 1;
        dup[0] = nums[0];
        for(int i=1; i<nums.length; i++){
            if(nums[i-1]!=nums[i]){
                dup[index] = nums[i]; 
                index+=1;
            }
        }

        for(int i=0; i<index; i++){
            nums[i] = dup[i];
        }
        return index;
    }
}

Approach 2 (Two Pointer)- This represents the accurate in-place methodology, stemming from the initial approach. It eliminates the necessity for creating a new array and utilizes the existing one. The first element remains unchanged as it represents the first distinct element encountered. Proceed to iterate through the array starting from the second element, checking whether the last copied element differs from the current one. If they are distinct, insert the current element into the subsequent position and continue the process.

class Solution {
    public int removeDuplicates(int[] nums) {
        int index = 0;

        for(int j=1; j<nums.length; j++){
            if(nums[index]!=nums[j]){
                index+=1;
                nums[index] = nums[j];
            }
        }
        return index+1;
    }
}