Even numbers at even index and odd numbers at odd index in Java

The process of arranging even numbers at even indices and odd numbers at odd indices requires arranging numbers inside an array so that even numbers are aligned at even indices (0, 2, 4, . . . ) and odd numbers are aligned at odd indices (1, 3, 5, . . . ) ensuring that numbers and their positions are of equal parity.

Example 1:

Input

Output

10 9 18 7 20 19 4 13 14 21                           

Explanation

Example 2:

Input

Output

2 5 8 7 6 1 4                                                                                                  

Explanation

Approach 1: Two-Pointer Approach

The Two Pointer Approach is a common technique used in array manipulation problems, and it is particularly useful for scenarios like rearranging arrays where elements need to be swapped or reordered based on certain conditions. The Two Pointer Approach involves using two pointers to traverse an array simultaneously, usually from opposite ends or with different increments and we will use two pointers to track the next positions for even and odd numbers.

Algorithm

Step 1: Take input an array arr[] and initialize two pointers, evenInd and oddInd, to track even and odd indices respectively: evenInd starts at index 0, oddInd starts at index 1.

Step 2: While Loop: Enter a while loop to iterate through the array until either evenInd or oddInd exceeds the array bounds.

Step 3: Even Index Movement: Inside the loop, use nested while loops: Move evenInd to the next even number.

Step 3.1: Increment evenInd by 2 until it reaches an even number or exceeds array bounds. If the current element at evenInd is already even, no movement is needed.

Step 4: Odd Index Movement: Similarly, move oddInd to the next odd number: Increment oddInd by 2 until it reaches an odd number or exceeds array bounds. If the current element at oddInd is already odd, no movement is needed.

Step 5: Swap Operation: If both evenInd and oddInd are within array bounds: Swap the elements at these indices and this places the even number found at evenInd into the even index and the odd number found at oddInd into the odd index.

Step 6: Termination: If either evenInd or oddInd exceeds the array bounds, exit the loop.

Step 7: After the loop completes, the array is rearranged with even numbers at even indices and odd numbers at odd indices. Print or return the modified array as the output.

Filename: EvenOddIndex.java

Output:

 
Original Array: 3 8 5 2 6 9 4 7 
Modified Array: 8 3 2 5 6 9 4 7

Time Complexity

The algorithm iterates through the array once with two pointers, evenInd and oddInd, moving forward based on certain conditions. As the array size increases, the time taken to traverse it linearly also increases proportionally. The time complexity is linear with respect to the size of the input array n that is O(n).

Space Complexity

The algorithm uses a constant amount of extra space regardless of the size of the input array that is O(1). It only requires a fixed number of variables to track the pointers (evenInd and oddInd) and some temporary space for swapping elements. The space used does not grow with the size of the input array.

Approach 2: Direct Swap Approach

The Direct Swap Approach is a technique used to arrange even numbers at even indices and odd numbers at odd indices in an array, this approach simplifies the logic by directly swapping elements at their correct indices, without using nested loops or multiple pointers.

Algorithm

Step 1: Take input an array arr[] and initialize two pointers, i and j, to 0 and 1 respectively, representing the starting indices for odd and even numbers.

Step 2: While Loop: Enter a while loop to traverse the array until either i or j exceeds the array bounds.

Step 3: Odd and Even Index Movement: Inside the loop, check conditions: If the number at i is odd and the number at j is even, swap them and move to the next pair of indices (i += 2, j += 2).

Step 4: If the number at i is even, move to the next odd index (i += 2). If the number at j is odd, move to the next even index (j += 2).

Step 5: Exit the loop when either i or j exceeds the array bounds and return the rearranged array.

Filename: DirectSwapApproach.java

Output:

 
Arranged Array 1: [6, 3, 12, 1, 8, 5]
Arranged Array 2: [10, 9, 18, 7, 20, 19, 4, 13, 14, 21]

Time Complexity

The algorithm iterates through the array once with two pointers, i and j, moving forward based on certain conditions. As the array size increases, the time taken to traverse it linearly also increases proportionally. The time complexity is linear with respect to the size of the input array n that is O(n).

Space Complexity

The algorithm has a constant space complexity that is O(1); as it uses only a fixed amount of extra space regardless of the size of the input array. It does not use any additional data structures that grow with the size of the input.

Approach 3: Extra Space Approach

The Extra Space Approach is a method to rearrange elements in an array such that even numbers are placed at even indices and odd numbers are placed at odd indices and this approach leverages additional space to temporarily store even and odd numbers separately before merging them back into the original array in the desired order.

Algorithm

Step 1: Create two empty lists, evenList and oddList, to temporarily store even and odd numbers, respectively.

Step 2: Initialize an array arrangedArr of the same length as the input array to store the final result.

Step 3: Separation Phase: Traverse the input array arr from start to end. For each element in the array: Check if the element is even or odd.

Step 4: If the element is even, add it to evenList. If the element is odd, add it to oddList.

Step 5: Merging Phase: Initialize two index variables, evenIndex and oddIndex, to 0 and 1, respectively.

Step 6: Traverse the evenList: Place each element of evenList into arrangedArr at positions specified by evenIndex. After placing each element, increment evenIndex by 2.

Step 7: Traverse the oddList: Place each element of oddList into arrangedArr at positions specified by oddIndex.

Step 8: After placing each element, increment oddIndex by 2. Return the arrangedArr as the final rearranged array.

Filename: ExtraSpaceApproach.java

Output:

Arranged Array 1: [6, 3, 12, 1, 8, 5]
Arranged Array 2: [10, 9, 18, 7, 4, 13, 20, 19, 14, 21]

Time Complexity

The algorithm iterates through the entire input array once to separate the even and odd numbers is of O(n) time complexity. The algorithm iterates through the even and odd lists to place their elements in the appropriate positions in the result array also of O(n), where n is the length of the input array. Hence, overall time complexity is O(n).

Space Complexity

The space complexity of the Extra Space Approach is O(n), where n is the number of elements in the input array. It is because the algorithm uses two additional lists (evenList and oddList) to store the even and odd numbers. In the worst case, the size of these lists combined will be equal to the size of the input array.

Approach 4: Sorting Approach

The Sorting Approach to rearranging an array such that even numbers are at even indices and odd numbers are at odd indices leverages sorting to facilitate the process and this method involves sorting the array to separate even and odd numbers and then placing them at their appropriate indices.

Algorithm

Step 1: Define a function arrangeArray that takes an integer array as input. Define a main method to test the function with example arrays.

Step 2: Sorting the Array: Sort the input array using Arrays.sort(arr). This ensures all even and odd numbers are grouped together.

Step 3: Setting Up Pointers: Initialize two pointers: evenIndex set to 0 and oddIndex set to 1. These pointers will be used to place even and odd numbers at their respective indices in the result array.

Step 4: Creating Result Array: Create a new array arrangedArr of the same length as the input array to store the rearranged elements.

Step 5: Placing Elements: Iterate over each element in the sorted array: If the element is even, place it at the next available even index (evenIndex) in the result array and increment evenIndex by 2.

Step 6: If the element is odd, place it at the next available odd index (oddIndex) in the result array and increment oddIndex by 2. Return the result array arrangedArr.

Filename: SortingApproach.java

Output:

 
Arranged Array 1: [6, 1, 8, 3, 12, 5]
Arranged Array 2: [4, 7, 10, 9, 14, 13, 18, 19, 20, 21]

Time Complexity

The initial step involves sorting the array, which has a time complexity of O(nlogn) using the Arrays.sort method. After sorting, we iterate through the array once to place the elements at their correct indices, which has a time complexity of O(n). The overall time complexity of this approach is O(nlogn).

Space Complexity

We create a new array, arrangedArr, of the same length as the input array to store the rearranged elements, it requires O(n) space. The sorting algorithm typically requires additional space. For example, if a merge sort is used, it requires O(n) auxiliary space. The overall space complexity of the approach is O(n).

Applications

  1. Data Organization
    Memory Layout Optimization: When data has a specific pattern, such as alternating even and odd numbers, organizing it can improve memory access patterns, leading to more efficient memory usage and faster computations. Database Management: Certain database queries or storage patterns might benefit from having data organized in a specific way to optimize retrieval and storage processes.
  2. Networking
    Packet Scheduling: Network packets can be scheduled in a pattern where even-numbered packets are given higher priority or routed differently compared to odd-numbered packets. This can be used for load balancing and ensuring quality of service (QoS). Error Detection and Correction: In communication systems, arranging data in specific patterns can be used to detect and correct errors more efficiently.
  3. Gaming and Simulation
    Game Development: In game development, organizing entities such as players or objects in a specific order can optimize rendering and collision detection processes. Simulations: In simulations that require alternate updates, such as cellular automata, having a structured order can improve the efficiency and accuracy of the simulation.