Another Edit:
(I think previous answer is still meaningful and I am keeping it at the end. This edit is mainly for suggestion specific to the homework requirement)
Base on the question, the compact logic treat 0 as something that is "meaningless" and need to be "removed". Therefore we don't really need some kind of special value after we "shrink" the array. Simply keeping it as 0 will help.
Apart from the "copy [i+1,end] to i" method, there is another (easier and possibly faster) method that you can do to "remove" the zeros.
Basically what you need is, iterate through the array. If you encounter a 0, then find the first non-zero value after that position, and swap the zero with that non-zero value.
Which looks like this in psuedo code:
for (i = 0; i < arr.length; i++) {
if (arr[i] == 0) {
for (j = i+1; j < arr.length; j++) {
if (arr[j] != 0) {
arr[i] = arr[j];
arr[j] = 0;
break;
}
}
}
}
// arr is "shrinked" here
Then it is your choice to return an actually shrinked copy of array, or simply return the "so-called-shrinked" array with 0s at the end.
Something for you to think of:
First, in Java, size of array is fixed, therefore, it is not possible to shrink array's size. Therefore, it is IMPOSSIBLE to have a result array with less elements without creating a new array
If it is fine for you to leave unused element at the end as some special values (e.g. -ve, or 0 etc), the removing element at position i from array essentially means:
copy array elements [i+1 to end] to position i, and replace arr[end] with special empty value
e.g. [1, 3, 5, 7, 9]
If I want to remove index 2, what I need to do is to copy element 3-4 to position 2:
[1,3,5,7,9] -> [1,3,7,9,9]
^^^ ^^^
and replace end element with some special value (e.g. -1 in this example):
[1,3,7,9,9] -> [1,3,5,7,-1]
Array copy can be done easily by using System.arrayCopy()
Have just seen update in your question.
Most of my answer is still valid, and here is some extra update with regards to your question:
- If you are sure that no Integer.MIN will appear in your input, then use my above mentioned approach, and update the input array accordingly.
- You may consider using Integer[] instead of int[], so that you can put null
- This is the most "normal" approach, but given your requirement, this may or may not be valid. The question ask you to have only scalar LOCAL VARIABLES. Which implies to me that, if I don't create another variable, I can still return another array (seems that the question is only trying to stop you using another array in process of compacting). Just follow what I have mentioned above, however, instead of replacing the end position with some special value, just keep a local var which is array length. Whenever you remove an element (by copying [i+1, 0] to position i), decrement the array length var. At the end, return a new copy of "shrinked" array by using
Arrays.copyOf(oldArray, newLength).
Here is a piece of psuedo-code for point 3:
int[] compact(int[] input) {
int arrSize = input.length;
int i = 0;
while (i < arrSize) {
if (input[i] == 0) {
copy input[i+1 to end] to input[i to end-1]
arrSize--;
} else {
i++;
}
}
return Arrays.copyOf(input, arrSize);
}
ArrayList?4, you cannot delete elements and make it length2.