Detailed analysis of Array algorithm problem

Posted by Aeglos on Sun, 28 Nov 2021 12:51:13 +0100

Detailed analysis of Array algorithm problem

Array related algorithm problems are relatively high frequency. Through this paper, I hope it can be helpful to your array related algorithm ability.

Find the largest and smallest elements in a given array

Problem Description:

Give you an array of numbers. You need to find the minimum and maximum numbers in the array.

Idea:

  • Define two variables max and min to store the maximum and minimum elements
  • Traversal array
    • If the current element is greater than max, the current element is assigned to max
    • If the current element is less than min, the current element is assigned to min
  • Finally, max and min are the largest and smallest elements

Code implementation:

public class FindLargestSmallestNumberMain {

    public static void main(String[] args) {

        int arr[] = new int[]{12,56,76,89,100,343,21,234};
        //Assign the first element to
        int min = arr[0];
        int max = arr[0];

        for(int i=1; i< arr.length; i++)
        {
            if(arr[i] > max)
                max = arr[i];
            else if (arr[i] < min)
                min = arr[i];
        }
        System.out.println("Smallest Number is : " + min);
        System.out.println("max Number is : " + max); 
    }
}

Copy code

Find missing numbers in array

Problem Description:

Given an integer increasing array containing 1 to n, but a number from 1 to n in the array is missing. You need to provide an optimal solution to find the missing numbers. Numbers do not repeat in the array.

For example:

int[] arr1={7,5,6,1,4,2};
Missing number : 3
int[] arr2={5,3,1,2};
Missing number : 4
 Copy code

Idea:

  • Because the elements in the array are increasing, you can use the formula n=n*(n+1)/2 to sum n numbers
  • Calculates the sum of elements in a given array
  • Subtract the sum of the elements in the array from the sum of n numbers, and the result is the missing number

Code implementation:

public class MissingNumberMain {
 
    public static void main(String[] args) {
 
        int[] arr1={7,5,6,1,4,2};
        System.out.println("Missing number from array arr1: "+missingNumber(arr1));
        int[] arr2={5,3,1,2};
        System.out.println("Missing number from array arr2: "+missingNumber(arr2));
 
    }
 
    public static int missingNumber(int[] arr)
    {
        int n=arr.length+1;
        int sum=n*(n+1)/2;
        int restSum=0;
        for (int i = 0; i < arr.length; i++) {
            restSum+=arr[i];
        }
        int missingNumber=sum-restSum;
        return missingNumber;
    }
}
Copy code

Find elements from a rotated ordered array

Problem Description:

Given a sorted and rotated array, as follows:

int arr[]={16,19,21,25,3,5,8,10};
Copy code

The array is obtained by rotating an ordered array arr[]={3,5,8,10,16,19,21,25}.

It is required to search for a specified element in the array of O(log n) time complexity.

Idea:

  • If the array is traversed directly, the time complexity is O(n), which does not meet the requirements of the topic;
  • Because the array is rotated by an ordered array, it is ordered before and after a subscript;
  • Then find it by dichotomy.

Algorithm logic:

  • Calculate the median subscript mid=(low+high)/2;
  • If arr[mid] is equal to the number to be searched, return;
  • If [low...mid] is ordered;
    • If the number to be searched is [low...mid], then high=mid-1;
    • If the number to be searched is not in [low...mid], then low=mid+1;
  • If [mid...high] is ordered;
    • If the number to be searched is [mid...high], then low=mid+1;
    • If the number to be searched is not in [mid...high], then high=mid-1;

Code implementation:

public class SearchElementSortedAndRotatedArrayMain {

    public static void main(String[] args) {
        int arr[] = {16, 19, 21, 25, 3, 5, 8, 10};
        System.out.println("Index of element 5 : " + findElementRotatedSortedArray(arr, 0, arr.length - 1, 5));
    }

    public static int findElementRotatedSortedArray(int[] arr, int low, int high, int number) {
        int mid;
        while (low <= high) {
            mid = low + ((high - low) / 2);

            if (arr[mid] == number) {
                return mid;
            }
            if (arr[mid] <= arr[high]) {
                // The right part is orderly
                if (number > arr[mid] && number <= arr[high]) {
                    low = mid + 1;
                } else {
                    high = mid - 1;
                }
            } else {
                // The left part is orderly
                if (arr[low] <= number && number < arr[mid]) {
                    high = mid - 1;
                } else {
                    low = mid + 1;
                }
            }
        }
        return -1;
    }
}
Copy code

Find the smallest element in the ordered rotation array

Problem Description:

The definition of ordered rotation array is the same as the same question, for example:

int arr[]={16,19,21,25,3,5,8,10};
Copy code

The time complexity is also required to be O(log n).

Idea:

Similar to the above question, because the array can be divided into two ordered arrays, it can be completed by a variant of the binary search method;

  • Calculate the median subscript mid=(low+high)/2;
  • If [mid...high] is ordered;
    • The minimum value is on the right, high=mid;
  • Otherwise, the minimum value is on the left, low= mid+1;

Code implementation:

public class MinimumElementSortedAndRotatedArrayMain {

    public static void main(String[] args) {
        int arr[] = {16, 19, 21, 25, 3, 5, 8, 10};
        System.out.println("Minimum element in the array : " + findMinimumElementRotatedSortedArray(arr, 0, arr.length - 1));
    }
    public static int findMinimumElementRotatedSortedArray(int[] arr, int low, int high) {
        int mid;
        while (low < high) {
            mid = low + ((high - low) / 2);
            if (arr[mid] < arr[high]) {
                high = mid;
            } else {
                low = mid+1;
            }
        }
        return arr[low];
    }
}
Copy code

Finds the second largest and element in the array

Problem Description:

Given a rotation ordered array, as follows:

int[] arr1={7,5,6,1,4,2};
Copy code

Find the second largest element: 6

Idea:

You can sort the array and then return the penultimate element in the array with a time complexity of O(nlogn).

  • Define the maximum value highest and the second largest value variable secondHighest
  • Traverse the array
  • If the current element is greater than the maximum value
    • Assign highest to secondHighest
    • Assign the current element to highest
  • Otherwise, if the current element is greater than secondHighest
    • Assign the current element to secondHighest

Code implementation:

public class FindSecondLargestMain {
    public static void main(String args[]) {
        int[] arr1 = {7, 5, 6, 1, 4, 2};
        int secondHighest = findSecondLargestNumberInTheArray(arr1);
        System.out.println("Second largest element in the array : " + secondHighest);
    }

    public static int findSecondLargestNumberInTheArray(int array[]) {
        int highest = Integer.MIN_VALUE;
        int secondHighest = Integer.MIN_VALUE;

        // Traversal array
        for (int i = 0; i < array.length; i++) {
            // If the current value is greater than the maximum value
            if (array[i] > highest) {
                // The maximum value is assigned to the second largest value
                secondHighest = highest;
                // The current value is assigned to the maximum value
                highest = array[i];
            } else if (array[i] > secondHighest && array[i] != highest)
                // Assign the current value to the second largest value
                secondHighest = array[i];
        }
        return secondHighest;
    }
}
Copy code

Find the number of odd occurrences in the array

Title Description:

Given an array of integers, only one number appears odd and the other numbers appear even. You need to find odd numbers. It needs O(n) time complexity and O(1) space complexity to solve it.

Idea 1:

Violent solution: use two-layer loops to record the number of occurrences of each element. The time complexity of this method is O(n^2), which is not the optimal solution.

Idea 2:

Using Hash, take the number as the key and the number of occurrences as the value. Whenever the key is repeated, value+1. The time complexity of this solution is O(n), but the space complexity is also O(n), which does not meet the requirements.

Code implementation:

int getOddTimesElementHashing(int ar[]) {
        int i;
        HashMap<Integer, Integer> elements = new HashMap<Integer, Integer>();
        for (i = 0; i < ar.length; i++) {
            int element = ar[i];
            if (elements.get(element) == null) {
                elements.put(element, 1);
            } else{
                elements.put(element, elements.get(element) + 1);
            }
        }
        for (Entry<Integer, Integer> entry : elements.entrySet()) {
            if (entry.getValue() % 2 == 1) {
                return entry.getKey();
            }
        }
        return -1;
    }
Copy code

Idea 3:

Exclusive or operation based on bit operation.

XOR operation: 0 for the same, 1 for the different. If a=1001,b=1010, then a^b=0010, a^a=0000.

According to the title description, only one number in the array appears odd times, and the other numbers are even times, the result of XOR operation of all numbers is the number that appears odd times.

Code implementation:

int getOddTimesElement(int arr[]) {
    int i;
    int result = 0;
    for (i = 0; i < arr.length; i++) {
        result = result ^ arr[i];
    }
    return result;
}
Copy code

The time complexity of the solution is O(n); Because only one variable result is used, the spatial complexity is O(1).

Calculate the minimum number of platforms required for the railway station

Title Description:

Given two arrays, corresponding to the arrival time and departure time of vehicles in the railway station, calculate the minimum number of platforms required by the railway station.

// Arrival schedule
arrival[] = {1:00, 1:40, 1:50, 2:00, 2:15, 4:00}
// Outbound timetable
departure[] = {1:10, 3:00, 2:20, 2:30, 3:15, 6:00}
// Minimum number of platforms required = 4
 Copy code

Idea 1:

Traverse the two arrays to check how much the arrival and outbound intervals overlap.

The time complexity of this method is O(n^2), which is not the optimal solution.

Idea 2:

Use merge sort logic.

  • Sort the arrival and departure arrays;
  • Because the number of arrivals and outbound is the same, take the elements at the same position from the two arrays and compare the time size;
  • If the arrival time is early, add 1 to the number of platforms;
  • If the departure time is early, the number of platforms will be reduced by 1;
  • Record the maximum number of platforms in this process;
  • Finally, return the value of the maximum number of stations.

The time complexity of this algorithm is O(n*log n).

Code implementation:

public class TrainPlatformMain {
    public static void main(String args[]) {
        // arr[] = {1:00, 1:40, 1:50, 2:00, 2:15, 4:00}
        // dep[] = {1:10, 3:00, 2:20, 2:30, 3:15, 6:00}
        int arr[] = {100, 140, 150, 200, 215, 400};
        int dep[] = {110, 300, 210, 230, 315, 600};
        System.out.println("Minimum number of platforms required =" + findPlatformsRequiredForStation(arr, dep, arr.length));
    }

    static int findPlatformsRequiredForStation(int arr[], int dep[], int n) {
        int platform_needed = 0, maxPlatforms = 0;
        Arrays.sort(arr);
        Arrays.sort(dep);
        int i = 0, j = 0;
        // Similar to merge operation in merge sort
        while (i < n && j < n) {
            if (arr[i] < dep[j]) {
                platform_needed++;
                i++;
                if (platform_needed > maxPlatforms)
                    maxPlatforms = platform_needed;
            } else {
                platform_needed--;
                j++;
            }
        }
        return maxPlatforms;
    }
}
Copy code

The two numbers in the array whose sum is closest to 0

Title Description:

An array has a series of positive and negative numbers. Find the two numbers in the array whose sum is closest to 0.

For example:

array[]={1,3,-5,7,8,20,-40,6};
// And the two numbers closest to 0 are: - 5 and 6
 Copy code

Idea 1:

Violent solution: sum all numbers in pairs. If the absolute value of the sum is smaller, assign a value and record the value of the two numbers.

The time complexity of this method is O(n^2), which is not the optimal solution.

Code implementation:

public static void findPairWithMinSumBruteForce(int arr[]) {
    if (arr.length < 2)
        return;
    // The sum of the first two preset numbers is closest to 0
    int minimumSum = arr[0] + arr[1];
    int pair1stIndex = 0;
    int pair2ndIndex = 1;
    for (int i = 0; i < arr.length; i++) {
        for (int j = i + 1; j < arr.length; j++) {
            int tempSum = arr[i] + arr[j];
            if (Math.abs(tempSum) < Math.abs(minimumSum)) {
                pair1stIndex = i;
                pair2ndIndex = j;
                minimumSum = tempSum;
            }
        }
    }
    System.out.println(" And the two numbers closest to 0 are : " + arr[pair1stIndex] + " " + arr[pair2ndIndex]);
}
Copy code

Idea 2:

  • Sort the array;
  • Define the start position l=0 of the array corresponding to two indexes, and the end position r=n-1;
  • Cycle according to the condition of L < R
  • Calculate the sum of arr[l]+arr[r]
  • If ABS (sum) < ABS (minsum), record l and r on the smallest two array element variables;
  • If sum > 0, if sum is closer to 0, move the large value to the small value, r --;
  • If sum < 0, the sum needs to move the small value to the large value to be closer to 0, l + +.

Code implementation:

public static void findPairWithMinSum(int arr[]) {
    Arrays.sort(arr);
    int sum = 0;
    int minimumSum = Integer.MAX_VALUE;
    int n = arr.length;
    // left and right index variables
    int l = 0, r = n - 1;

    int minLeft = l, minRight = n - 1;

    while (l < r) {
        sum = arr[l] + arr[r];
        // If ABS (sum) < ABS (minsum), record l and r on the smallest two array element variables;
        if (Math.abs(sum) < Math.abs(minimumSum)) {
            minimumSum = sum;
            minLeft = l;
            minRight = r;
        }
        if (sum < 0)
            l++;
        else
            r--;
    }
    System.out.println(" And the two numbers closest to 0 are : " + arr[minLeft] + " " + arr[minRight]);
}
Copy code

The time complexity of the algorithm is O(NLogN).

The two numbers in the array whose sum is closest to X

This problem is an advanced version of the previous problem. Find the number whose sum of the two numbers is closest to X.

Idea 1:

Violent solution: two-level cycle. The sum is compared with the nearest number. If it is smaller, the corresponding number is recorded. The time complexity is O(n^2), which is not the optimal solution.

Idea 2:

The difference from the previous question is that the value to be compared with the summation result is the specified X, not 0, and the result of abs() function cannot be directly used for comparison; How to deal with it?

By subtracting X from the abs() result, the solution to the problem can be.

  • Sort the array;
  • Define the start position l=0 of the array corresponding to two indexes, and the end position r=n-1;
  • Cycle according to the condition of L < R
  • Calculate the result diff of arr[l]+arr[r]-x
  • If ABS (diff) < mindiff, record l and r on the smallest two array element variables;
  • If sum > x, if sum is closer to x, move the large value to the small value, r --;
  • If sum < x, if sum is closer to x, move the small value to the large value, l + +.

Code implementation:

public static void findPairWithClosestToX(int arr[], int X) {
    Arrays.sort(arr);
    int minimumDiff = Integer.MAX_VALUE;
    int n = arr.length;

    int l = 0, r = n - 1;

    int minLeft = l, minRight = n - 1;
    while (l < r) {
        int currentDiff = Math.abs(arr[l] + arr[r] - X);
        // If ABS (diff) < mindiff, record l and r on the smallest two array element variables
        if (currentDiff < minimumDiff) {
            minimumDiff = currentDiff;
            minLeft = l;
            minRight = r;
        }
        if (arr[l] + arr[r] < X)
            l++;
        else
            r--;
    }
    System.out.println(" And closest X The two numbers are : " + arr[minLeft] + " " + arr[minRight]);
}
Copy code

All combinations in which the sum of two numbers in the array is equal to X

Title Description:

Given an array and a specified number, find the combination in which the sum of all two numbers in the array is equal to the specified number.

Idea 1:

The two-level cyclic violence solution has low time complexity and is not the optimal solution.

Code implementation:

public static void findPairsWithSumEqualsToXBruteForce(int arr[], int X) {
    if (arr.length < 2)
        return;
    System.out.println("The sum of the two numbers is equal to X Combination of: ");
    for (int i = 0; i < arr.length; i++) {
        for (int j = i + 1; j < arr.length; j++) {
            int tempSum = arr[i] + arr[j];

            if (tempSum == X) {
                System.out.println(arr[i] + " " + arr[j]);
            }
        }
    }
}
Copy code

Idea 2:

Sort the array;

Traverse from both ends of the array until they meet. Use l for the left and r for the right;

If arr[l]+arr[r]=X, the conditions are met, and the results are printed, l--,r--;

If arr [l] + arr [r] > x, it means that the result is too large and the large value needs to be reduced, r --;

If arr [l] + arr [R] < x, it means that the result is too small, and the small value needs to be increased, L + +;

Code implementation:

public static void findPairsEqualsToX(int arr[], int X) {
    int n = arr.length;
    if (n < 2)
        return;
    Arrays.sort(arr);
    System.out.println("The sum of the two numbers equals X Combination of: ");

    int l = 0, r = n - 1;

    while (l < r) {
        int currentSum = arr[l] + arr[r];
        if (currentSum == X) {
            System.out.println(arr[l] + " " + arr[r]);
            l++;
            r--;
        } else if (arr[l] + arr[r] < X)
            l++;
        else
            r--;
    }
}
Copy code

The time complexity of the solution is O(NLogN).

Idea 3:

  • Using HashMap, put the value of the array element as the key and the subscript as the value into the map;
  • Traversal array;
  • If X-arr[i] exists in the HashMap, the result will be taken from the Map, indicating that the conditions are met.

Code implementation:

public static void findPairsEqualsToXUsingHashing(int arr[], int X) {
    HashMap<Integer, Integer> elementIndexMap = new HashMap<>();
    System.out.println("The sum of the two numbers equals X Combination of: ");
    for (int i = 0; i < arr.length; i++) {
        elementIndexMap.put(arr[i], i);
    }
    for (int i = 0; i < arr.length; i++) {
        if (elementIndexMap.get(X - arr[i]) != null && elementIndexMap.get(X - arr[i]) != i) //
        {
            System.out.println(arr[i] + " " + (X - arr[i]));
        }
    }
}
Copy code

Topics: Java Algorithm leetcode Back-end Programmer