Sort Array By Parity II

Here’s another easy-level LC problem. My initial solution uses two pointers: One to keep track of the index of the next even number and another for odd number.

I go through each element and if it’s an even index with an odd number, we’ll try to find the closest even number and swap them. Same thing goes with the odd index. I didn’t like the code as it is too messy and difficult to understand.

class Solution {
    fun sortArrayByParityII(A: IntArray): IntArray {
        val isEven: (Int) -> Boolean = { it % 2 == 0 }
        var evenIndex = 0
        var oddIndex = 0
        A.mapIndexed { index, i -> 
            when(isEven(index)){
                true -> if(!isEven(i)) {
                    // find the next even
                    oddIndex = index
                    for(subIndex in index until A.size){
                        if(isEven(A[subIndex])) {
                            evenIndex = subIndex
                            break
                        }
                    }
                    
                    // swap
                    val temp = A[evenIndex]
                    A[evenIndex] = A[index]
                    A[index] = temp
                } else evenIndex = index
                
                else -> if(isEven(i)) {
                    // find the next odd
                    evenIndex = index
                    for(subIndex in index until A.size){
                        if(!isEven(A[subIndex])) {
                            oddIndex = subIndex
                            break
                        }
                    }
                    
                    // swap
                    val temp = A[oddIndex]
                    A[oddIndex] = A[index]
                    A[index] = temp
                }else oddIndex = index
            }
            
        }
    
        return A
    }
}
Runtime: 340 ms, faster than 15.79% of Kotlin online submissions for Sort Array By Parity II.
Memory Usage: 39.5 MB, less than 100.00% of Kotlin online submissions for Sort Array By Parity II.

Then I figured out another solution in which we have to pass through each element and group them by their parity.

val grouped = A.groupBy { it % 2 == 0 }

This will give you a map with two entries: false key contains list of odd numbers and true key contains list of even numbers. According to the problem:

A.length % 2 == 0

So we’re sure that our array will always be divided into equal number of odd and even numbers. With this, we can say that in order to arrange the numbers into alternating parity, all we have to do is loop through N/2 or just the size of all even numbers and then assign the odd and even numbers accordingly.

class Solution {
    fun sortArrayByParityII(A: IntArray): IntArray {
        val grouped = A.groupBy { it % 2 == 0 }
        var evenList = grouped[true]
        var oddList = grouped[false]
        
        Pair(evenList, oddList).let {
            val evenList = it.first!!
            val oddList = it.second!!
            var arrayIndex = 0
            for(index in 0 until evenList.size){
                A[arrayIndex++] = evenList[index]
                A[arrayIndex++] = oddList[index]
            }
        }
        
        return A
    }
}

Code is a lot cleaner and easier to understand. Plus, it’s also a bit faster than my original implementation.

Runtime: 264 ms, faster than 57.89% of Kotlin online submissions for Sort Array By Parity II.
Memory Usage: 39.2 MB, less than 100.00% of Kotlin online submissions for Sort Array By Parity II.
comments powered by Disqus