Lexicographical Array Problem You are given an array A of size N

0

Lexicographical Array Problem

Problem Statement:

You are given an array A of size N. You are allowed to choose at most one pair of elements such that distance (defined as the difference of their indices) is at most K and swap them.

Find the smallest lexicographical array possible after swapping.

Notes: An array x is lexicographically smaller than an array y if there exists an index i such that xi<yi, and xj=yj for all 0≤j<i. Less formally, at the first index i in which they differ, xi<yi.

Parameters:

N :: INTEGER

The first line contains an integer, N, denoting the number of elements in A.

N :: 1 -> 10^5

A :: INTEGER ARRAY

Each line i of the N subsequent lines (where 0 ≤ i < N) contains an integer describing A[i].

A[i] :: 1 -> 10^5 K :: INTEGER

The next line contains an integer, K, denoting the upper bound on distance of index.

K :: 1 -> N

Example Cases:

Case #1

Input:

3
2
2
2
1

Output:

2
2
2

Here, as all the array values are equal, swapping will not change the final result.

Case #2

Input:

5
5
4
3
2
1
3

Output:

2
4
3
5
1

Here, A = [5, 4, 3, 2, 1], K = 3. We can swap elements at index 0 and index 3 to get A = [2, 4, 3, 5, 1].

Case #3

Input:

5
2
1
1
1
1
3

Output:

1
1
1
2
1

Here, A = [2, 1, 1, 1, 1], K = 3. We can swap elements at index 0 and index 3 to get A = [1, 1, 1, 2, 1].

Lexicographical Array - Java Code


import java.util.*;

public class LexicographicalArray {
    public static int[] findSmallestLexArray(int[] A, int K) {
        int N = A.length;
        // Create a copy of the original array
        int[] result = Arrays.copyOf(A, N);
        
        // For each position, try to find a smaller element within K distance
        // that we can swap to make the array lexicographically smaller
        for (int i = 0; i < N; i++) {
            int minValue = result[i];
            int minIndex = i;
            
            // Look for the smallest value within K distance
            for (int j = i + 1; j < Math.min(N, i + K + 1); j++) {
                if (result[j] < minValue) {
                    minValue = result[j];
                    minIndex = j;
                }
            }
            
            // If we found a smaller element, swap it and break
            // We only need to make one swap to get the lexicographically smallest array
            if (minIndex != i) {
                int temp = result[i];
                result[i] = result[minIndex];
                result[minIndex] = temp;
                break;
            }
        }
        
        return result;
    }
    
    public static void main(String[] args) {
        // Test cases
        test(new int[]{2, 2, 2}, 1);
        test(new int[]{5, 4, 3, 2, 1}, 3);
        test(new int[]{2, 1, 1, 1, 1}, 3);
    }
    
    private static void test(int[] A, int K) {
        System.out.println("\nInput Array: " + Arrays.toString(A));
        System.out.println("K: " + K);
        int[] result = findSmallestLexArray(A, K);
        System.out.println("Result: " + Arrays.toString(result));
    }
}
    

Solution Explanation

This solution implements the following approach:

  • The main method findSmallestLexArray takes an array A and distance K as input.
  • For each position in the array, it looks for the smallest element within K distance that could be swapped to make the array lexicographically smaller.
  • Once it finds such a swap, it performs the swap and returns the result (since we're only allowed one swap).
  • The solution has a time complexity of O(N*K) where N is the length of the array.

Test Cases

The program includes test cases for all three examples you provided:

  • [2,2,2] with K=1 - no changes needed
  • [5,4,3,2,1] with K=3 - swaps to get [2,4,3,5,1]
  • [2,1,1,1,1] with K=3 - swaps to get [1,1,1,2,1]

Lexicographically Smallest Array Code in Python


def find_smallest_lex_array(A, K):
    """
    Find the lexicographically smallest array possible after at most one swap
    within distance K.
    
    Args:
        A (list): Input array of integers
        K (int): Maximum allowed distance between swapped elements
    
    Returns:
        list: The lexicographically smallest possible array after at most one swap
    """
    N = len(A)
    # Create a copy of the original array
    result = A.copy()
    
    # For each position, try to find a smaller element within K distance
    # that we can swap to make the array lexicographically smaller
    for i in range(N):
        min_value = result[i]
        min_index = i
        
        # Look for the smallest value within K distance
        for j in range(i + 1, min(N, i + K + 1)):
            if result[j] < min_value:
                min_value = result[j]
                min_index = j
        
        # If we found a smaller element, swap it and break
        # We only need to make one swap to get the lexicographically smallest array
        if min_index != i:
            result[i], result[min_index] = result[min_index], result[i]
            break
    
    return result

def test_case(A, K):
    """Helper function to run and display test cases"""
    print(f"\nInput Array: {A}")
    print(f"K: {K}")
    result = find_smallest_lex_array(A, K)
    print(f"Result: {result}")
    return result

# Test cases
def run_test_cases():
    # Test Case 1: All equal elements
    assert test_case([2, 2, 2], 1) == [2, 2, 2]
    
    # Test Case 2: Descending array
    assert test_case([5, 4, 3, 2, 1], 3) == [2, 4, 3, 5, 1]
    
    # Test Case 3: Array with repeating elements
    assert test_case([2, 1, 1, 1, 1], 3) == [1, 1, 1, 2, 1]
    
    # Additional test case: Already sorted array
    test_case([1, 2, 3, 4, 5], 2)
    
    print("\nAll test cases passed!")

if __name__ == "__main__":
    run_test_cases()
    

Python Solution Overview

The Python solution follows the same approach as before but with some Python-specific improvements:

  • Uses Python's more concise syntax for swapping elements: a, b = b, a
  • Includes docstrings for better documentation
  • Uses assertion-based testing to verify correctness
  • Implements a clean test case helper function

Key features of the solution:

  • Time complexity: O(N*K) where N is the length of the array
  • Space complexity: O(N) due to creating a copy of the input array
  • The algorithm makes at most one swap to achieve the lexicographically smallest array
  • Includes comprehensive test cases including the three provided examples

Test Case Example:

To run additional test cases, you can simply call the test_case function with your input:

test_case([3, 1, 4, 1, 5], 2)  #Custom test case

C Code Example

This is a simple C code example to demonstrate the use of test cases:


#include <stdio.h>
#include <stdlib.h>

// Function to run test case
void testCase(int A[], int N, int K) {
    int* result = (int*)malloc(N * sizeof(int));
    
    printf("\nInput Array: ");
    printArray(A, N);
    printf("K: %d\n", K);
    
    findSmallestLexArray(A, N, K, result);
    
    printf("Result: ");
    printArray(result, N);
    
    free(result);
}

int main() {
    // Test Case 1: All equal elements
    int test1[] = {2, 2, 2};
    printf("Test Case 1:");
    testCase(test1, 3, 1);
    
    // Test Case 2: Descending array
    int test2[] = {5, 4, 3, 2, 1};
    printf("\nTest Case 2:");
    testCase(test2, 5, 3);
    
    // Test Case 3: Array with repeating elements
    int test3[] = {2, 1, 1, 1, 1};
    printf("\nTest Case 3:");
    testCase(test3, 5, 3);
    
    return 0;
}
    

C Implementation - Lexicographically Smallest Array

Key Components

findSmallestLexArray: The main function that implements the algorithm

  • Takes input array, size N, distance K, and result array as parameters
  • Finds and performs at most one swap to create lexicographically smallest array
  • Time complexity: O(N*K)

Helper Functions

  • printArray: Utility function to print arrays
  • testCase: Function to run and display test cases

Memory Management

  • Uses dynamic memory allocation for result array
  • Properly frees allocated memory after use

Test Cases

  1. Case 1: [2, 2, 2] with K=1
  2. Case 2: [5, 4, 3, 2, 1] with K=3
  3. Case 3: [2, 1, 1, 1, 1] with K=3

To Compile and Run


        gcc lexicographical_array.c -o lexicographical_array
        ./lexicographical_array
    

To Use the Program with Your Own Test Case

You can add it to main():


        int your_test[] = {3, 1, 4, 1, 5};
        testCase(your_test, 5, 2);
    

Lexicographical Array in C++

Below is the C++ code to find the smallest lexicographical array with a given K distance.


#include <iostream>
#include <vector>
#include <algorithm>

class LexicographicalArray {
private:
    std::vector<int> A;
    int K;
    int N;

public:
    // Constructor
    LexicographicalArray(const std::vector<int>& arr, int k) : A(arr), K(k) {
        N = A.size();
    }

    // Function to find smallest lexicographical array
    std::vector<int> findSmallestLexArray() {
        std::vector<int> result = A;  // Create a copy of original array
        
        // For each position, try to find a smaller element within K distance
        for (int i = 0; i < N; i++) {
            int minValue = result[i];
            int minIndex = i;
            
            // Look for the smallest value within K distance
            for (int j = i + 1; j < std::min(N, i + K + 1); j++) {
                if (result[j] < minValue) {
                    minValue = result[j];
                    minIndex = j;
                }
            }
            
            // If we found a smaller element, swap it and break
            if (minIndex != i) {
                std::swap(result[i], result[minIndex]);
                break;
            }
        }
        
        return result;
    }

    // Function to print array
    static void printArray(const std::vector<int>& arr) {
        for (int num : arr) {
            std::cout << num << " ";
        }
        std::cout << std::endl;
    }
};

// Test case runner class
class TestRunner {
public:
    static void runTest(const std::vector<int>& arr, int k) {
        std::cout << "\nInput Array: ";
        LexicographicalArray::printArray(arr);
        std::cout << "K: " << k << std::endl;
        
        LexicographicalArray solver(arr, k);
        std::vector<int> result = solver.findSmallestLexArray();
        
        std::cout << "Result: ";
        LexicographicalArray::printArray(result);
    }

    static void runAllTests() {
        // Test Case 1: All equal elements
        std::cout << "Test Case 1:";
        runTest({2, 2, 2}, 1);
        
        // Test Case 2: Descending array
        std::cout << "\nTest Case 2:";
        runTest({5, 4, 3, 2, 1}, 3);
        
        // Test Case 3: Array with repeating elements
        std::cout << "\nTest Case 3:";
        runTest({2, 1, 1, 1, 1}, 3);
        
        // Additional Test Case: Already sorted array
        std::cout << "\nAdditional Test Case:";
        runTest({1, 2, 3, 4, 5}, 2);
    }
};

int main() {
    TestRunner::runAllTests();
    return 0;
}
    

C++ Lexicographical Array Implementation

Improvements Over C Version:

Object-Oriented Design:

  • LexicographicalArray class encapsulates the array and algorithm
  • TestRunner class handles test case execution
  • Uses proper encapsulation with private members and public interface

Modern C++ Features:

  • Uses std::vector for dynamic arrays
  • Uses range-based for loops
  • Uses std::swap for element swapping
  • Implements const correctness
  • Uses references to avoid unnecessary copying

Memory Management:

  • Automatic memory management through std::vector
  • No manual memory allocation/deallocation needed

Test Cases:

  • Includes all three original test cases
  • Adds an additional test case with a sorted array
  • Organized test runner class

Usage:

To use the program with your own test case:

std::vector customTest = {3, 1, 4, 1, 5};
TestRunner::runTest(customTest, 2);

To Compile and Run:

g++ -std=c++11 lexicographical_array.cpp -o lexicographical_array
./lexicographical_array

Complexity:

  • Time complexity: O(N*K)
  • Space complexity: O(N)
  • Makes at most one swap to achieve the lexicographically smallest array

Post a Comment

0Comments
Post a Comment (0)

#buttons=(Accept !) #days=(20)

Our website uses cookies to enhance your experience. Learn More
Accept !
✨ Updates
  • 👉 Dive into Kali Linux and explore advanced cybersecurity techniques with GeeksCodes.💕
  • 👉 Build a standout resume and showcase your skills effectively with GeeksCodes.💕
  • 👉 Stay updated with the latest trends in tech, cybersecurity, and digital marketing GeeksCodes.💕