tags:

views:

301

answers:

4

Return an array that contains the exact same numbers as the given array, but rearranged so that all the zeros are grouped at the start of the array. The order of the non-zero numbers does not matter. So {1, 0, 0, 1} becomes {0 ,0, 1, 1}. You may modify and return the given array or make a new array.

zeroFront({1, 0, 0, 1}) → {0, 0, 1, 1}
zeroFront({0, 1, 1, 0, 1}) → {0, 0, 1, 1, 1}
zeroFront({1, 0}) → {0, 1}

Here is what I have, but I know that it is incredibly wrong.

public int[] zeroFront(int[] nums) {

  for (int index = 0; index < nums.length; index ++)
  {
     int [] array1 = new int [index]; 
     if (nums [index] == 0)
     {
        array1 = nums [index]; 
     }
  }
  for (int index = 0; index < nums.length; index ++)
  {
     int [] array2 = new int [nums.length-index]; 
     if (nums [index] != 0)
     {
        array2 = nums [index]; 
     }
  }
  return array1 + array2;       
}
A: 

The sort method won't work for negative numbers, and the other way won't work for some cases (see comments).

The easiest (and shortest) way would be to sort the array (Works only for non-negative numbers, thanks Tom):

Arrays.sort(nums);

Another way would be to swap values when you find a non 0 :

int lastNonZero = -1;
for(int i = 0; i < nums.length; i++) {
  if(nums[i] == 0 && lastNonZero!=-1) {
     int tmp = nums[i];
     nums[i] = nums[lastNonZero];
     nums[lastNonZero] = tmp;
     lastNonZero = -1;
  }
  else lastNonZero = i;
}
Soufiane Hassou
Won't work if there are negative numbers!
Tom
Your swapping code is confusing. Also, you don't need a temporary value and I have no idea why you are using -1. The code just looks wrong... why do you always set lastNonZero back to -1?? See my answer.
Tom
The swapping code is the classical "swapping" code I don't see what's confusing, I'm sure there's a built-in swap function, but this works too. As for lastNonZero, if your last found number is a 0 and you already found a nonZero, then you swap values, and you don't need to swap anything else until you find another nonZero and a Zero.
Soufiane Hassou
It's wrong because of an array like this: {1, 2, 0}. When you reach the first 0, you will swap with 2 instead of 1, which is incorrect. It is also incorrect with {1, 0, 0}. The reason is that with your code, you will never swap a 0 after you just swapped! if you swap, you set lastNonZero to -1. Which means on the next iteration of the for loop, if nums[i] == 0, lastNonZero will be -1, so you don't swap. Make sense?
Tom
Thanks Tom, I see my mistake now :-) I'll leave this answer for Educational purposes :D"Don't do what I'm doing" :-)
Soufiane Hassou
+1  A: 

Didn't test this, but should work:

public int[] zeroFront(int[] nums) {
  if (nums == null) {
    return null;
  }

  int[] result = new int[nums.length];
  int zeroesPos = 0;
  int othersPos = result.length - 1;
  for (int i = 0; i < nums.length; ++i) {
    if (nums[i] == 0) {
      result[zeroesPos] = 0;
      ++zeroesPos;
    } else {
      result[othersPos] = nums[i];
      --othersPos;
    }
  }
  return result;
}

This fills a new array up by scanning over the old one, and filling zeroes from the front and other numbers from the back. You can do something similar "in place" if you don't want to return a new array. You can keep track of where the next 0 should go and when you see it, swap it with the number at zeroesPos. Like this:

public void zeroFrontInPlace(int[] nums) {
  if (nums == null) {
    return;
  }

  int zeroesPos = 0;
  for (int i = 0; i < nums.length; ++i) {
    if (nums[i] == 0) {
      nums[i] = nums[zeroesPos];  // move the non-zero number to position i
      nums[zeroesPos] = 0;  // move the zero toward the front
      ++zeroesPos;
    }
  }
}

Notice you don't have to do a normal swap where you create a temporary value since you know the value is 0.

Hope this helps.

Tom
Yep, and if you swap on 0 instead of just setting it directly then I think you can do the "sort" right in the original array. It's a simplified version of the "Dutch national flag problem".
PSpeed
Swap on both branches, of course. And I could swear that last paragraph wasn't there when I originally responded. Too quick to send.
PSpeed
+1  A: 

Havent tested either but this should be much simpler..

public int[] zeroFront(int[] nums) {
      if (nums == null) {
        return null;
      }
       int zerosPos = 0;

      for (int i = 0; i < nums.length; ++i) {
        if (nums[i] == 0) {      //swap zerosPos with current position
            num[i]=num[zerosPos];
            num[zerosPos]=0;
          ++zerosPos;
             }
      }
      return num;
    }

hope this helped!!

RDJ

Richie
You don't need a temp, because you know the value of num[i]. You can just say num[i] = nums[zerosPos]; num[zerosPos++] = 0;
novalis
yea..thanks novalis..i will edit it..
Richie
code fixed!! :-)
Richie
A: 

For the example data shown, the array could simply be sorted.

If they are not representative, then write a Comparator which compares Math.abs(number) instead of number, and use that for sorting.

Thorbjørn Ravn Andersen
I was thinking the same thing... but while that may be "clever", sorting is O(nlogn), while the solution I (and others) proposed is O(n).
Tom
Depends on this is homework or not.
Thorbjørn Ravn Andersen
What does this being hw or not have to do with time complexity of the algorithm?
Tom
Unless there is an absolute requirement for a given implementation (usual for homework) and the data is small "enough", it is usually the best to keep it simple. Delegating to a library routine is a good way to do so.
Thorbjørn Ravn Andersen