I want to implement Merge Sort using one a mergeSort method that splits the sequences of an int array up until it's a single element and using a method merge to put them together.
With my code as it is I get a Stackoverflow Error.
Anyone has an idea why?
public static int[] mergeSort(int[] seq) {
return mergeSort(seq, 0, seq.length - 1);
}
private static int[] mergeSort(int[] seq, int l, int r) {
if (seq.length < 2) {
return seq;
}
int s = (l + r) / 2;
int[] a = new int[s];
int[] b = new int[seq.length - s];
for (int i : a) {
a[i] = seq[i];
}
for (int j : b) {
b[j] = seq[s + j];
}
mergeSort(a);
mergeSort(b);
return merge(a, b);
}
public static int[] merge(int[] ls, int[] rs) {
// Store the result in this array
int[] result = new int[ls.length + rs.length];
int i, l, r;
i = l = r = 0;
while (i < result.length) {
if (l < ls.length && r < rs.length) {
if (ls[l] < rs[r]) {
result[i] = ls[l];
++i;
++l;
} else {
result[i] = rs[r];
++i;
++r;
}
} else if (l >= ls.length) {
while (r < rs.length) {
result[i] = rs[r];
++i;
++r;
}
} else if (r >= rs.length) {
while (l < ls.length) {
result[i] = ls[l];
++i;
++l;
}
}
}
return result;
}
The stack overflow is caused by calling the method recursively too many times, possibly infinitely.
private static int[] mergeSort(int[] seq, int l, int r) this will always be called with l=0 and r=seq.length-1, so it's not really necessary to overload.
Here: int s = (l + r) / 2; if the array has 2 elements, this will return 0 (l=0, r=1), so the array will be split to a length 0, and a length 2 (and here is what causes the infinite recursive calls). Add one to the result, and the splitting of the array will work correctly.
To copy the parts of the original array, it's easier to use Arrays.copyOfRange() than writing your own for loop. And you're trying to use the existing elements of arrays a and b, which will all be 0, for indexing.
There are two small issues with your code.
First one is here:
public static int[] mergeSort(int[] seq) {
return mergeSort(seq, 0, seq.length - 1);
}
You need to call it as return mergeSort(seq, 0, seq.length);
The reason behind that is that for example when you have 2 elements and you call it like that with -1 you pass an array with 2 elements but s=1+0/2 =0 and you don't actually split it. Each subsequent recursion call is done with one empty array and one array with the same 2 elements causing an infinite loop and a stackoverflow exception
The second problem is this one:
for (int i : a) { and for (int i : b) {
You can't do the for loop like because you want to iterate on indexes not values of the array. You need to change it to:
for (int i=0;i<a.length;i++) {
a[i] = seq[i];
}
for (int i=0;i<b.length;i++) {
b[i] = seq[s + i];
}
And the last problem with your code is that you don't assign the values of the resulting sorted array and when you do the recursive calls it returns the sorted sub part but you don't get the result. It should become:
a=mergeSort(a);
b=mergeSort(b);
And here is the final code:
public static void main(String... args) {
int[] array={3,9,4,5,1} ;
array=mergeSort(array);
for(int i:array) {
System.out.print(i+",");
}
}
private static int[] mergeSort(int[] seq) {
if (seq.length < 2) {
return seq;
}
int s = seq.length / 2; //You always use that value. no need for 2 methods
int[] a = new int[s];
int[] b = new int[seq.length - s];
for (int i=0;i<a.length;i++) {
a[i] = seq[i];
}
for (int i=0;i<b.length;i++) {
b[i] = seq[s + i];
}
a=mergeSort(a);
b=mergeSort(b);
return merge(a, b);
}
public static int[] merge(int[] ls, int[] rs) {
// Store the result in this array
int[] result = new int[ls.length + rs.length];
int i, l, r;
i = l = r = 0;
while (i < result.length) {
if (l < ls.length && r < rs.length) {
if (ls[l] < rs[r]) {
result[i] = ls[l];
++i;
++l;
} else {
result[i] = rs[r];
++i;
++r;
}
} else if (l >= ls.length) {
while (r < rs.length) {
result[i] = rs[r];
++i;
++r;
}
} else if (r >= rs.length) {
while (l < ls.length) {
result[i] = ls[l];
++i;
++l;
}
}
}
return result;
}
Related
I have implemented a merge sort and would like to run it concurrently.
Merge sort works as follows:
i. Divide the unsorted list into n sublists, each containing 1 element (a list of 1 element
is considered sorted).
ii. Repeatedly merge sublists to produce new sorted sublists until there is only 1 sublist remaining. This will be the sorted list.
The split function is provided below,
public void mergeSort(int[] arr) {
if (arr.length <= 1) {
return;
}
int mid = arr.length / 2;
int[] leftSubArray = Arrays.copyOfRange(arr, 0, mid);
int[] rightSubArray = Arrays.copyOfRange(arr, mid, arr.length);
mergeSort(leftSubArray);
mergeSort(rightSubArray);
merge(arr, leftSubArray, rightSubArray);
}
The method for the merge is provided,
private void merge(int[] arr, int[] left_subArray, int[] right_subArray) {
int i = 0, j = 0;
int index = 0;
while ((i < left_subArray.length) && (j < right_subArray.length)) {
if (left_subArray[i] <= right_subArray[j]) {
arr[index++] = left_subArray[i++];
} else {
arr[index++] = right_subArray[j++];
}
}
while (i < left_subArray.length) {
arr[index++] = left_subArray[i++];
}
while (j < right_subArray.length) {
arr[index++] = right_subArray[j++];
}
}
The program is working fine and I thought it might work more efficiently is run concurrently. The code is here,
public void concurrMergeSort(int[] arr, int numOfThreads) {
if (numOfThreads <= 1) {
mergeSort(nums);
return;
}
/*
split the array in left and right parts
*/
int middleIndex = arr.length / 2;
int[] leftArray = Arrays.copyOfRange(arr, 0, middleIndex);
int[] rightArray = Arrays.copyOfRange(arr, middleIndex, arr.length);
Thread left = mergeSortThread(leftArray, numOfThreads);
Thread right = mergeSortThread(rightArray, numOfThreads);
left.start();
right.start();
try {
left.join();
right.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
merge(arr, leftArray, rightArray);
}
private Thread mergeSortThread(int[] arr, int numOfThreads) {
return new Thread() {
#Override
public void run() {
// split the thread by half
concurrMergeSort(arr, numOfThreads / 2);
}
};
}
Is the implementation is correct?
I've implemented the Heap's algorithm for finding all permutations of the elements of array A:
//A = {1, 2, 3, 4}; B = perms(A) ; num_row(B) = (4!+1) and B[0][0] = 4!;
//This is B.R. Heap's algorithm
public static void perms(int [] A, int [][]B, int n)
{
if (n == 1)
{
int k = B[0][0];
for (int i = 0; i < A.length; i++)
{
B[k + 1][i] = A[i];
}
B[0][0]++;
}
else
{
for (int i = 0; i < n - 1 ;i++)
{
perms(A, B, n-1);
if (n % 2 == 0)
{
swap(A, i, n - 1);
}
else
{
swap(A, 0, n - 1);
}
}
perms(A, B, n - 1);
}
}
public static void swap(int[] A, int i, int j)
{
int temp = A[i];
A[i] = A[j];
A[j] = temp;
}
I'm new to Java. The problem is I want to have B as the output (return) of the function perms(A) , but in this implementation, I have to initialize a int[n! + 1][A.length] B array before calling the function. How can I do it?
Is there anything like private variable or anything in java to help a recursive function to remember a variable from a former call?
Thanks
You can create an "entering" method to recursion like this:
public static int[][] perms(int[] a){
int[][] perms = new int[factorial(a.length)+1][a.length];
perms(a,perms,a.length);
return perms;
}
Method factorial is well know method and can be found on Google for example
Wondering if n parameter is neccessary
EDIT
it is not neccessary (above corrected)
EDIT
By my test the k variable is just incrementing, so I would use static variable like this:
private static int counter = 0;
// your code here, following is a part of your perms method
if (n == 1)
{
for (int i = 0; i < A.length; i++)
{
B[counter][i] = A[i];
}
counter++;
}
//and my code corrected too:
public static int[][] perms(int[] a){
int[][] perms = new int[factorial(a.length)][a.length]; //+1 is not necessary
counter=0; //necessary to call it again
perms(a,perms,a.length);
return perms;
}
I have implemented the select/median of medians algorithm using the following as a reference http://www.ics.uci.edu/~eppstein/161/960130.html (this has previously been linked here Median of Medians in Java).
My code seems to work for small arrays (~100) and even works for arrays of size 100001 http://pastebin.com/mwRc4Hig (answer 5008), but then fails on an input array of size 10001 http://pastebin.com/YwVBmgDk (answer 4960, my code outputs 4958).
Note that the correct answers for the texts above are equivalent to sorting the array and returning the element at array[array.length / 2], regardless of whether the array size is even or odd.
I'm not sure how to debug this issue. The functionality seems arbitrary and I'm just lost. Here below is my code:
public class MedianOfMedians {
public static void main(String[] args) {
MedianOfMedians mds = new MedianOfMedians();
mds.run();
}
private void run() {
Scanner in = new Scanner(System.in);
int n = in.nextInt();
int[] numArray = new int[n];
for (int i = 0; i < n; i++) {
numArray[i] = in.nextInt();
}
int median = select(numArray, numArray.length / 2);
System.out.print(median);
}
private int select(int[] numArray, int k) {
if (numArray.length <= 10) {
int[] sorted = insertionSort(numArray);
return sorted[k];
}
int divCount = (numArray.length % 5 == 0) ? numArray.length / 5 - 1 : numArray.length / 5;
int[] medOfMed = new int[divCount + 1];
int counter = 0;
int[] subArray;
while (counter <= divCount) {
subArray = splitByFive(counter, divCount, numArray);
medOfMed[counter] = select(subArray, subArray.length / 2);
counter++;
}
int M = select(medOfMed, numArray.length / 10);
List<Integer> lt = new ArrayList<>();
List<Integer> eq = new ArrayList<>();
List<Integer> gt = new ArrayList<>();
for (int i : numArray) {
if (i < M) {
lt.add(i);
} else if (i == M) {
eq.add(i);
} else {
gt.add(i);
}
}
if (k < lt.size()) {
return select(createArray(lt), k);
} else if (k > lt.size() + eq.size()) {
return select(createArray(gt), k - lt.size() - eq.size());
} else {
return M;
}
}
private int[] splitByFive(int splitIter, int divisions, int[] toSplit) {
int numToCopy;
if (splitIter == divisions) {
numToCopy = toSplit.length - (5 * splitIter);
} else {
numToCopy = 5;
}
int[] subArray = new int[numToCopy];
System.arraycopy(toSplit, splitIter * 5, subArray, 0, numToCopy);
return subArray;
}
private int[] createArray(List<Integer> list) {
int[] result = new int[list.size()];
for (int i = 0; i < list.size(); i++) {
result[i] = list.get(i);
}
return result;
}
private int[] insertionSort(int[] numArray) {
for (int i = 1; i < numArray.length; i++) {
int j = i;
while (j - 1 >= 0 && numArray[j] < numArray[j - 1]) {
int temp = numArray[j];
numArray[j] = numArray[j - 1];
numArray[j - 1] = temp;
j--;
}
}
return numArray;
}
}
I don't have time to debug your code, but maybe I can offer a debugging technique for you to try yourself that's useful for recursive algorithms like this.
If there is an input that the algorithm fails on (and there is, as you found) then there is a smallest such input -- and the smaller this input, the easier it is to figure out what's going wrong. Because the algorithm is recursive, you have a nice way to isolate the first place that things go wrong: you can test that the result you are about to return from select() is correct (using a slow, trusted method like copying the data to a temporary buffer, sorting it and then grabbing the half-way element) just before returning the value. Doing this will be much easier if you rearrange the function to use just a single return statement, e.g.:
private int select(int[] numArray, int k) {
int knownCorrectAnswer = selectSlowlyButDefinitelyCorrectly(numArray, k);
int willReturn;
if (numArray.length <= 10) {
int[] sorted = insertionSort(numArray);
willReturn = sorted[k]; // Just remember what we will return
} else { // Need to add else branch here now
...
if (k < lt.size()) {
willReturn = select(createArray(lt), k);
} else if (k > lt.size() + eq.size()) {
willReturn = select(createArray(gt), k - lt.size() - eq.size());
} else {
willReturn = M;
}
} // End of inserted else branch
if (willReturn == knownCorrectAnswer) {
return willReturn;
} else {
yell("First problem occurs with numArray=<...> and k=<...>!");
}
}
yell() should print out the entire problem instance and halt the program (e.g. by throwing an exception). The nice thing about this setup is that you know that when yell() gets called, every call to select() that has already completed was correct -- since if it wasn't, yell() would have already been called and the program would have halted before now. So the output produced by yell() is guaranteed to be the first (not necessarily the smallest, but often that also) subproblem in which things went wrong.
public class intersect {
public static void find(int[] a, int[] b, int[] acc)
{
int position = 0;
for (int j = 0; j < a.length; j++) {
for (int k = 0; k<b.length; k++) {
if (a[j] == b[k]) {
acc[position] = b[k];
position++;
}
}
}
System.out.println(java.util.Arrays.toString(acc));
}
public static void main (String[] s)
{
int[] acc = new int[2];
int[] a = {1,2,3};
int[] b = {2,3,4};
find(a, b, acc);
}
}
I have written the above code to solve the problem.
But if you see, the function is very limited because I have to change the length of the acc every time. That means I have to know how many elements are intersecting. In this case, the array {1,2,3} and {2,3,4} have {2,3} in common, so the length of the acc would be 2.
I am sure there are millions of ways of tackling this problem, but I cannot seem to think of a way of fixing this.
Please help!
If your professor wants you to use arrays, you can use the following method:
public static int[] resize(int[] arr)
{
int len = arr.length;
int[] copy = new int[len+1];
for (int i = 0; i < len; i++)
{
copy[i] = arr[i];
}
return copy;
}
This will increase the size of the array by 1. You can use that instead. By the way, you're not using the fact that they're sorted in your find() method. What you should do is this:
public static void find(int[] a, int[] b, int[] acc)
{
int a_index = 0, b_index = 0, acc_index = -1;
int a_element, b_element;
while (a_index < a.length && b_index < b.length)
{
a_element = a[a_index]; b_element = b[b_index];
if (a_element == b_element)
{
acc = resize(acc);
acc[++acc_index] = a_element;
a_index++; b_index++;
} else if (b_element < a_element) {
b_index++;
} else {
a_index++;
}
}
System.out.println(java.util.Arrays.toString(acc));
}
This method is more efficient now. Working example.
To find intersection of 2 sorted arrays, follow the below approach :
1) Use two index variables i and j, initial values with 0
2) If array1 is smaller than array2 then increment i.
3) If array1 is greater than array2 then increment j.
4) If both are same then print any of them and increment both i and j.
check this link for more information
https://www.geeksforgeeks.org/union-and-intersection-of-two-sorted-arrays-2/
public class FindIntersection {
static void findInterSection(int array1[], int array2[], int array1NoOfElements, int
array2NoOfElements) {
int i = 0, j = 0;
while (i < array1NoOfElements && j < array2NoOfElements) {
if (array1[i] < array2[j]) {
i++;
} else if (array2[j] < array1[i]) {
j++;
}
// if both array elements are same
else {
System.out.println(array2[j++] + " ");
i++;
}
}
}
public static void main(String[] args)
{
int myFirstArray[] = { 1, 2, 4, 5, 5 };
int mySecondArray[] = { 2, 3, 5, 7 };
int m = myFirstArray.length;
int n = mySecondArray.length;
findInterSection(myFirstArray, mySecondArray, m, n);
}
}
Make your intersection array's size the size of the smaller of your original arrays. That way, you won't ever have to increase it's capacity.
Then you can use Arrays.copy to transfer your results into an appropriately sized array.
Not sure if this is the best solution, but you don't need to hard-code the size of the intersection ahead of time (which is one thing you were concerned about).
As you iterate through both arrays, you can add elements found in both sets to a StringBuilder (along with some delimiter, I used a comma in the example below). Once you're finished, you can call toString() & then split() using the delimiter afterwards to get a String[]. At that point, you can put convert those String objects to int primitives & return an int[].
public class Scratch {
public static void main(String[] s) {
int[] a = {1, 2, 3};
int[] b = {2, 3, 4};
int[] intersection = findIntersection(a, b);
System.out.println(Arrays.toString(intersection));
}
public static int[] findIntersection(int[] a, int[] b) {
StringBuilder intersectionStringBuilder = new StringBuilder();
for (int j = 0; j < a.length; j++) {
for (int k = 0; k < b.length; k++) {
if (a[j] == b[k])
intersectionStringBuilder.append(a[j] + ",");
}
}
String[] intersectionStringArray = intersectionStringBuilder.toString().split(",");
int[] intersection = new int[intersectionStringArray.length];
for (int current = 0; current < intersectionStringArray.length; current++) {
intersection[current] = Integer.parseInt(intersectionStringArray[current]);
}
return intersection;
}
}
for(int i=0;i<arr1.length;i++){
for(int j=0;j<arr2.length;j++){
if(arr1[i]==arr2[j] && !index.contains(j)){
list.add(arr1[i]);
index.add(j);
break;
}
}
}
int result[]=new int[list.size()];
int k=0;
for(int i:list){
result[k]=i;
k++;
}
for(int i=0;i<result.length;i++){
System.out.println(result[i]);
}
return result;
}
I had an interview question which i could not solve.
Write method (not a program) in Java Programming Language that will move all even numbers on the first half and odd numbers to the second half in an integer array.
E.g. Input = {3,8,12,5,9,21,6,10}; Output = {12,8,6,10,3,5,9,21}.
The method should take integer array as parameter and move items in the same array (do not create another array). The numbers may be in different order than original array. This is algorithm test, so try to give as efficient algorithm as you can (possibly linear O(n) algorithm). Avoid using built in functions/API. *
Also some basic intro to what is data structure efficiency
Keep two indices: one to the first odd number and one to the last even number. Swap such numbers and update indices.
(With a lot of help from #manu-fatto's suggestion) I believe this would do it:
private static int[] OddSort(int[] items)
{
int oddPos, nextEvenPos;
for (nextEvenPos = 0;
nextEvenPos < items.Length && items[nextEvenPos] % 2 == 0;
nextEvenPos++) { }
// nextEvenPos is now positioned at the first odd number in the array,
// i.e. it is the next place an even number will be placed
// We already know that items[nextEvenPos] is odd (from the condition of the
// first loop), so we'll start looking for even numbers at nextEvenPos + 1
for (oddPos = nextEvenPos + 1; oddPos < items.Length; oddPos++)
{
// If we find an even number
if (items[oddPos] % 2 == 0)
{
// Swap the values
int temp = items[nextEvenPos];
items[nextEvenPos] = items[oddPos];
items[oddPos] = temp;
// And increment the location for the next even number
nextEvenPos++;
}
}
return items;
}
This algorithm traverses the list exactly 1 time (inspects each element exactly once), so the efficiency is O(n).
// to do this in one for loop
public static void evenodd(int[] integer) {
int i = 0, temp = 0;
int j = integer.length - 1;
while (j >= i) {
// swap if found odd even combo at i and j
if (integer[i] % 2 != 0 && integer[j] % 2 == 0) {
temp = integer[i];
integer[i] = integer[j];
integer[j] = temp;
i++;
j--;
} else {
if (integer[i] % 2 == 0) {
i++;
}
if (integer[j] % 2 == 1) {
j--;
}
}
}
}
#JLRishe,
Your algorithm doesn't maintain the order. For a simple example, say {1,5,2}, you will change the array to {2,5,1}. I could not comment below your post as I am a new user and lack reputations.
public static void sorted(int [] integer) {
int i, j , temp;
for (i = 0; i < integer.length; i++) {
if (integer[i] % 2 == 0) {
for (j = i; j < integer.length; j++) {
if (integer[j] % 2 == 1) {
temp = y[i];
y[i] = y[j];
y[j] = temp;
}
}
}
System.out.println(integer[i]);
}
public static void main(String args[]) {
sorted(new int[]{1, 2,7, 9, 4});
}
}
The answer is 1, 7, 9, 2, 4.
Could it be that you were asked to implement a very basic version of the BubbleSort where the sort value of element e, where e = arr[i], = e%2==1 ? 1 : -1 ?
Regards
Leon
class Demo
{
public void sortArray(int[] a)
{
int len=a.length;
int j=len-1;
for(int i=0;i<len/2+1;i++)
{
if(a[i]%2!=0)
{
while(a[j]%2!=0 && j>(len/2)-1)
j--;
if(j<=(len/2)-1)
break;
a[i]=a[i]+a[j];
a[j]=a[i]-a[j];
a[i]=a[i]-a[j];
}
}
for(int i=0;i<len;i++)
System.out.println(a[i]);
}
public static void main(String s[])
{
int a[]=new int[10];
System.out.println("Enter 10 numbers");
java.util.Scanner sc=new java.util.Scanner(System.in);
for(int i=0;i<10;i++)
{
a[i]=sc.nextInt();
}
new Demo().sortArray(a);
}
}
private static void rearrange(int[] a) {
int i,j,temp;
for(i = 0, j = a.length - 1; i < j ;i++,j--) {
while(a[i]%2 == 0 && i != a.length - 1) {
i++;
}
while(a[j]%2 == 1 && j != 0) {
j--;
}
if(i>j)
break;
else {
temp = a[i];
a[i] = a[j];
a[j] = temp;
}
}
}
public void sortEvenOddIntegerArray(int[] intArray){
boolean loopRequired = false;
do{
loopRequired = false;
for(int i = 0;i<intArray.length-1;i++){
if(intArray[i] % 2 != 0 && intArray[i+1] % 2 == 0){
int temp = intArray[i];
intArray[i] = intArray[i+1];
intArray[i+1] = temp;
loopRequired = true;
}
}
}while(loopRequired);
}
You can do this with a single loop by moving odd items to the end of the array when you find them.
static void EvensToLeft(int[] items) {
int end = items.length;
for (int i = 0; i < end; i++) {
if (items[i] % 2) {
int t = items[i];
items[i--] = items[--end];
items[end] = t;
}
}
}
Given an input array of length n the inner loop executes exactly n times, and computes the parity of each array element exactly once.
Use two counters i=0 and j=a.length-1 and keep swapping even and odd elements that are in the wrong place.
public int[] evenOddSort(int[] a) {
int i = 0;
int j = a.length - 1;
int temp;
while (i < j) {
if (a[i] % 2 == 0) {
i++;
} else if (a[j] % 2 != 0) {
j--;
} else {
temp = a[i];
a[i] = a[j];
a[j] = temp;
i++;
j--;
}
}
return a;
}
public class SeperatOddAndEvenInList {
public static int[] seperatOddAndEvnNos(int[] listOfNumbers) {
int oddNumPointer = 0;
int evenNumPointer = listOfNumbers.length - 1;
while(oddNumPointer <= evenNumPointer) {
if(listOfNumbers[oddNumPointer] % 2 == 0) { //even number, swap to front of last known even number
int temp;
temp = listOfNumbers[oddNumPointer];
listOfNumbers[oddNumPointer] = listOfNumbers[evenNumPointer];
listOfNumbers[evenNumPointer] = temp;
evenNumPointer--;
}
else { //odd number, go ahead... capture next element
oddNumPointer++;
}
}
return listOfNumbers;
}
public static void main(String[] args) {
// TODO Auto-generated method stub
int []arr = {3, 8, 12, 5, 9, 21, 6, 10};
int[] seperatedArray = seperatOddAndEvnNos(arr);
for (int i : seperatedArray) {
System.out.println(i);
}
}
}
public class ArraysSortEvensFirst {
public static void main(String[] args) {
int[] arr = generateTestData();
System.out.println(Arrays.toString(arr));
ArraysSortEvensFirst test = new ArraysSortEvensFirst();
test.sortEvensFirst(arr);
}
private static int[] generateTestData() {
int[] arr = {1,3,5,6,9,2,4,5,7};
return arr;
}
public int[] sortEvensFirst(int[] arr) {
int end = arr.length;
int last = arr.length-1;
for(int i=0; i < arr.length; i++) {
// find odd elements, then move to even slots
if(arr[i]%2 > 0) {
int k = findEven(last, arr);
if(k > i) swap(arr, i, k);
last = k;
}
}
System.out.println(Arrays.toString(arr));
return arr;
}
public int findEven(int last, int[] arr) {
for(int k = last; k > 0; k--) {
if(arr[k]%2 == 0) {
return k;
}
}
return -1; // not found;
}
public void swap(int[] arr, int x, int y) {
int temp = arr[x];
arr[x] = arr[y];
arr[y] = temp;
}
}
Output:
[1, 3, 5, 6, 9, 2, 4, 5, 7]
[4, 2, 6, 5, 9, 3, 1, 5, 7]
efficiency is O(log n).
public class TestProg {
public static void main(String[] args) {
int[] input = { 32, 54, 35, 18, 23, 17, 2 };
int front = 0;
int mid = input.length - 1;
for (int start = 0; start < input.length; start++) {
//if current element is odd
if (start < mid && input[start] % 2 == 1) {
//swapping element is also odd?
if (input[mid] % 2 == 1) {
mid--;
start--;
}
//swapping element is not odd then swap
else {
int tmp = input[mid];
input[mid] = input[start];
input[start] = tmp;
mid--;
}
}
}
for (int x : input)
System.out.print(x + " ");
}
}