making a method to remove the zeros from an array in java - java

was curious on how to write a method to remove all zeros from an array. If I have the array in the main method. for example my Main Method would look something like
public static void main(String[] args) {
int[] test = {1, 0, 4, 7, 0, 2, 10, 82, 0};
System.out.println(Arrays.toString(test) + ": length = " + test.length);
int[] result = removeZeros(test);
System.out.println(Arrays.toString(result) + ": length = " + result.length);
}
and have the code output the length and the array without the zeros like:
[1, 0, 4, 7, 0, 2, 10, 82, 0]: length = 9
[1, 4, 7, 2, 10, 82]: length = 6
I don't know how to write a method for this other than doing something like this:
int[] test = {1, 0, 4, 7, 0, 2, 10, 82, 0};
int length = 0;
for (int i=0; i<test.length; i++){
if (test[i] != 0)
length++;
}
int [] intResult = new int[length];
for (int i=0, j=0; i<test.length; i++){
if (test[i] != 0) {
intResult[j] = test[i];
j++;
}
}
any ideas how to make this a method and have it print out both the original array and the new array without zeros in it + the length?

I didn't test it, but this should work:
public class Blah {
public static void main(String[] args) {
int[] test = {1, 0, 4, 7, 0, 2, 10, 82, 0};
System.out.println(Arrays.toString(test) + ": length = " + test.length);
int[] result = removeZeros(test);
System.out.println(Arrays.toString(result) + ": length = " + result.length);
}
public int[] removeZeros(int[] test) {
int length = 0;
for (int i=0; i<test.length; i++){
if (test[i] != 0)
length++;
}
int [] intResult = new int[length];
for (int i=0, j=0; i<test.length; i++){
if (test[i] != 0) {
intResult[j] = test[i];
j++;
}
return intResult;
}
}

With only the slightest changes to your own code, it's this simple to make it a method.
int [] removeZeros(int [] test);
{
if (test == null) {
return null;
}
int length = 0;
for (int i=0; i<test.length; i++){
if (test[i] != 0)
length++;
}
int [] intResult = new int[length];
for (int i=0, j=0; i<test.length; i++){
if (test[i] != 0) {
intResult[j] = test[i];
j++;
}
}
return intResult;
}

any ideas how to make this a method and have it print out both the original array and the new array without zeros in it + the length?
There is no significantly better way to remove the zeros. Obviously, you can put it in a method ... if that's what you want to do. The method needs to create and return the new array. (You can't change the size of the array argument passed to the method ...)
To print an array, either use a loop to iterate and print the elements, or Arrays.toString(array) and output the string.
To print an array's length, print array.length.

Using Java 8 :
int[] test = {1, 0, 4, 7, 0, 2, 10, 82, 0}
int[] result = Arrays.stream(test).filter(i -> i != 0).toArray();

How about this
create array result with same length of array input
use variable length to count length of expected result
if the current element of input more than zero, result[length] =
current element of input test[i] and length++
If the length more than 0 then cut array result using value of length
The code :
int[] test = {1, 0, 4, 7, 0, 2, 10, 82, 0};
int[] intResult = new int[test.length];
int length = 0;
for (int i=0; i<test.length; i++){
if (test[i] > 0) {
intResult[length] = test[i];
length++;
}
}
if(length > 0)intResult = Arrays.copyOf(intResult, length);

Related

Combing two arrays in ascending order with unknown values inside the array

I have managed to create both arrays, however I can't figure out how to combine the two arrays. Every tutorial I see merges them as such:
int[] arr1 = {3, 3, 5, 6, 8, 9};
int[] arr2 = {3, 4, 5, 6};
// Output: 3, 4, 5, 6, 8, 9
What I need is something that would output: 3, 3, 3, 4, 5, 5, 6, 6, 8, 9
Here is the code I have written so far:
import java.util.Scanner;
public class Merger {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
int[] arr1 = new int[10000];
int[] arr2 = new int[10000];
int[] merged = new int[20000];
int a1 = 0;
int a2 = 0;
int size = -1;
int size2 = -1;
int sizecheck = 0;
int size2check = 0;
System.out
.println("Enter the values for the first array, up to 10,000 values, enter a negative number to quit");
for (int i = 0; i < arr1.length; i++) {
arr1[i] = scan.nextInt();
merged[i] = arr1[i];
if (arr1[i] <= 0) {
break;
}
if (size <= arr1[i]) {
size = arr1[i];
sizecheck++;
}
a1++;
}
System.out
.println("Enter the values for the second array, up to 10,000 values, enter a negative number to quit");
for (int i = 0; i < arr2.length; i++) {
arr2[i] = scan.nextInt();
merged[i + a1] = arr2[i];
if (arr2[i] <= 0) {
break;
}
if (size2 <= arr2[i]) {
size2 = arr2[i];
size2check++;
}
a2++;
}
System.out.println("First Array: ");
for (int i = 0; i < a1; i++) {
System.out.print(" " + arr1[i]);
}
System.out.println("\nSecond Array: ");
for (int i = 0; i < a2; i++) {
System.out.print(" " + arr2[i]);
}
}
}
This prints both arrays out, however does not combine and sort the two.
Here's the code ! There may be a faster/easier way to do it but this one works as long as the 2 arrays are sorted
public static void main(String[] args) {
int[] a1 = {1, 2, 3, 5};
int[] a2 = {1, 3, 4, 4, 4, 5};
int[] a3 = merge(a1, a2);
for (int i : a3) {
System.out.print(i);
}
}
public static int[] merge(int[] a1, int[] a2) {
int[] a3 = new int[a1.length + a2.length];
int indexA1 = 0;
int indexA2 = 0;
for (int i = 0; i < a3.length; i++) {
int n;
if (indexA1 == a1.length && indexA2 < a2.length) {
n = a2[indexA2];
indexA2++;
} else if (indexA1 < a1.length && indexA2 == a2.length) {
n = a1[indexA1];
indexA1++;
} else {
if (a1[indexA1] < a2[indexA2]) {
n = a1[indexA1];
indexA1++;
} else {
n = a2[indexA2];
indexA2++;
}
}
a3[i] = n;
}
return a3;
}
I assume that you are not yet familiar with Streams, but I would like to give you an example of what you can do with them.
Add import
import java.util.stream.IntStream;
Add this at the end of your main method
System.out.println("");
IntStream arr1Stream = IntStream.of(arr1).limit(a1); //creates an InStream with the first a1 values of arr1
IntStream arr2Stream = IntStream.of(arr2).limit(a2);
int[] both = IntStream.concat(arr1Stream, arr2Stream).sorted().toArray(); //combines the two streams, sorts them an converts them to an Array
System.out.println(Arrays.toString(both)); //easy way to print an array
The easiest way is to use a Stream.
int[] arr1 = {3, 3, 5, 6, 8, 9};
int[] arr2 = {3, 4, 5, 6};
Stream both arrays.
flatMap them to a single IntStream
sort them
convert to an array
int [] combined = Stream.of(arr1,arr2)
.flatMapToInt(Arrays::stream)
.sorted()
.toArray();
System.out.println(Arrays.toString(combined));
Prints
[3, 3, 3, 4, 5, 5, 6, 6, 8, 9]
A non-stream approach can be done as follows:
// increase arr1 to make room for arr2
int oldLen = arr1.length;
arr1 = Arrays.copyOf(arr1, arr1.length+arr2.length);
// copy arr2 starting at 0, to arr1 starting at the old length
// positon of arr1 for a length of arr2
System.arraycopy(arr2, 0, arr1, oldLen, arr2.length);
// sort and print
Arrays.sort(arr1);
System.out.println(Arrays.toString(arr1));
Prints
[3, 3, 3, 4, 5, 5, 6, 6, 8, 9]
Although your question, as asked, said nothing about merging sorted arrays, here is how you would do it.
The algorithm is simple. Just iterate thru each array and compare current values.
if arr1[i] <= arr2[k], copy arr1[i] to result, advance i by 1
else copy arr2[k] to result, advance k by 1.
in all cases the index to result, r, is advanced by 1
public int[] merge(int[] arr1, int[] arr2) {
// result array
int[] result = new int[arr1.length + arr2.length];
int r = 0;
int k = 0;
int i = 0;
// Iterate thru the arrays, copying the lowest or equal value
// to the target array. This process will cease when one of the arrays
// has been fully processed.
for (; i < arr1.length && k < arr2.length; ) {
for (; k < arr2.length && i < arr1.length;) {
if (arr1[i] <= arr2[k]) {
result[r++] = arr1[i++];
}else {
result[r++] = arr2[k++];
}
}
}
Having reached this far in the algorithm, one of the arrays must have been completely processed. So try and copy both. For the empty array, the while loop basically acts like an if statement.
while (i < arr1.length) {
result[r++] = arr1[i++];
}
while (k < arr2.length) {
result[r++] = arr2[k++];
}
// return the result
return result;
}
public class Merger {
public static void main(String[] args) {
int[] arr1 = { 3, 3, 5, 6, 8, 9 };
int[] arr2 = { 3, 4, 5, 6 };
int[] res = merge(arr1, arr2);
System.out.println(Arrays.toString(res));
}
public static int[] merge(int[] arr1, int[] arr2) {
int[] res = new int[arr1.length + arr2.length];
for (int i = 0, a1 = 0, a2 = 0; i < res.length; i++) {
if (a1 == arr1.length)
res[i] = arr2[a2++];
else if (a2 == arr2.length)
res[i] = arr1[a1++];
else
res[i] = arr1[a1] <= arr2[a2] ? arr1[a1++] : arr2[a2++];
}
return res;
}
}
A simple solution can be written using the classes, Arrays and System.
Steps:
Copy elements of arr1[] into a new array (say, output[]) whose size is the sum of the sizes of the given arrays.
Copy the elements of arr2[], after the element of arr1[], into output[]
Sort output[]
Demo:
import java.util.Arrays;
public class Main {
public static void main(String[] args) {
int[] arr1 = { 3, 3, 5, 6, 8, 9 };
int[] arr2 = { 3, 4, 5, 6 };
// Copy elements of arr1[] into a new array whose size is the sum of the sizes
// of the given arrays
int[] output = Arrays.copyOf(arr1, arr1.length + arr2.length);
// Copy the elements of arr2[], after the element of arr1[], into output[]
System.arraycopy(arr2.clone(), 0, output, arr1.length, arr2.length);
// Sort output[]
Arrays.sort(output);
// Display output[]
System.out.println(Arrays.toString(output));
}
}
Output:
[3, 3, 3, 4, 5, 5, 6, 6, 8, 9]
You can use System.arraycopy method for this purpose:
int[] arr1 = {3, 3, 5, 6, 8, 9};
int[] arr2 = {3, 4, 5, 6};
// create a new array of total length
int[] arr3 = new int[arr1.length + arr2.length];
// copy first array to the beginning of the total array
System.arraycopy(arr1, 0, arr3, 0, arr1.length);
// copy second array to the end of the total array
System.arraycopy(arr2, 0, arr3, arr1.length, arr2.length);
// sort the total array
Arrays.sort(arr3);
System.out.println(Arrays.toString(arr3));
// [3, 3, 3, 4, 5, 5, 6, 6, 8, 9]

Find an array of Keys(a pattern) in an given array

Im working on this problem for 2 hrs now, and my mind stopped working. And Im getting no where. Can someone please help?
The question is match the exact pattern from a Key array to another array.
For example:
Key = {3, 8, 6}
Target = {3, 6, 8, 8, 6, 3, 8, 6, 2, 4}
the answer here would be the indexes at which these are found, which would be:
{5, 6, 7}
This code solves problem:
int[] key = new int[]{3, 8, 6};
int[] target = new int[]{3, 6, 8, 8, 6, 3, 8, 6, 2, 4};
for (int i = 0; i < target.length; i++) {
int j = 0;
for (j = 0; j < key.length && (i + j) < target.length; j++) {
if (target[i + j] != key[j]) {
break;
}
}
if (j == key.length && j != 0) {
System.out.print("{");
for (j = 0; j < key.length; j++) {
System.out.print(i + j);
if (j != key.length - 1) {
System.out.print(", ");
}
}
System.out.println("}");
}
}
HashMap<Integer, Integer> maps = new HashMap<>();
IntStream.range(0, target.length).forEach(i -> {
maps.put(target[i], i);
});
Arrays.stream(src).forEach(i -> {
System.out.println(maps.get(i));
});
Calculate the index firstly, it likes the group by, but only choose last. finally we can easily get the index from this Hash.
char[] key = {3, 8, 6};
char[] target = {3, 6, 8, 8, 6, 3, 8, 6, 2, 4};
String keyStr = new String( key );
String targetStr = new String( target );
int start = targetStr.indexOf( keyStr );
int[] resultArr = new int[key.length];
int x = 0;
for(int i = start; i< start + key.length; i++)
{
resultArr[ x] = i;
x++;
}
System.out.println( Arrays.toString( resultArr ));
if you want to match multiple times then use:
char[] key = {3, 8, 6};
char[] target = {3, 6, 8, 8, 6, 3, 8, 6, 2, 4, 3, 8, 6};
String keyStr = new String( key );
String targetStr = new String( target );
Pattern pattern = Pattern.compile( keyStr );
Matcher matcher = pattern.matcher( targetStr );
// Check all occurrences
while( matcher.find() )
{
System.out.print( "Start index: " + matcher.start() );
System.out.print( " End index: " + matcher.end() );
int start = matcher.start();
int[] resultArr = new int[key.length];
int x = 0;
for( int i = start; i < start + key.length; i++ )
{
resultArr[x] = i;
x++;
}
System.out.println( Arrays.toString( resultArr ) );
}
You can create subarrays of your target array with the length of your key array and compare each sub array with the key:
import java.util.Arrays;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
public class OBJ {
public static void main(String[] args){
int[] key = {3, 8, 6};
int[] target = {3, 6, 8, 8, 6, 3, 8, 6, 2, 4};
for(int i = 0; i < target.length - key.length; i++){
int[] temp = Arrays.copyOfRange(target, i, i+key.length);
if(Arrays.equals(key,temp)){
String indices = IntStream.range(i, i+key.length).mapToObj(e->String.valueOf(e)).collect(Collectors.joining(","));
System.out.println(indices);
}
}
}
}
You should pass through all the elements in the "target" array and also hold some index to follow after the currently match pattern from the "key" array, let's call this index "keyIndex". Every time that the element from the "target" array is equal to the element at the "keyIndex" position from the "key" array, you increment keyIndex (the currently match pattern is larger) and add to some data structure (I choose list) the index from the "target" array in which the elements are equal. If the elements are not equal, you should reset the "keyIdnex" (The currently match pattern is have length of zero) and clear the list.
I believe this should be good for you:
public static List<Integer> findPattern(int[] key , int[] target){
List<Integer> result = new ArrayList<Integer>(); //This list hold the indexes of the patter
int keyIndex = 0; //The index to follow after the "key" array
for(int i = 0 ; i < target.length; i++){
if(target[i] == key[keyIndex]){ //This "key" element is equal to the element from the "target"
result.add(i); //Add the index in which the elements are equal.
keyIndex++; //The currently match pattern is larger, increment "keyIndex"
if(result.size() == key.length) //The all pattern is checked and match, return the list which store the indexes
return result;
}else{ //The pattern is not match anymore, reset all the data
keyIndex = 0;
i--;
result.clear();
}
}
return null; //The pattern from "key" not found in "target" ,return null
}
Try this,
public static void main(String args[]) {
int[] a = { 1, 5, 7, 3, 6, 10, 9, 8, 3, 6, 7, 10, 9, 8 };
int[] key = { 3, 6, 10 };
List<Integer> pos = new ArrayList<Integer>();
for (int i = 0; i <= a.length - key.length; i++) {
pos = getPosition(i, a, key);
if (pos != null)
System.err.println(pos);
}
}
private static List<Integer> getPosition(int i, int[] a, int[] key) {
int count = 0;
List<Integer> p = new ArrayList<Integer>();
for (int j = 0; i < a.length && j < key.length; i++, j++) {
if (a[i] == key[j]) {
count++;
p.add(i);
}
}
return count == key.length ? p : null;
}

Inserting an integer into a sorted array

I'm trying to write a method that takes a sorted array and an integer, creates a new array that is 1 size larger, and inserts the new integer and keeps it sorted.
I've tried a few different implementations and had them to work - but for this specific one, I can't grasp where it's going wrong.
int[] array1 = new int[]{1, 2, 3, 4, 6, 7, 8};
int[] printArray = insert(array1, 5);
are the arrays, and the method is
public static int[] insert(int[] a, int k) {
int[] s = new int[a.length + 1];
for(int i = 0; i < a.length; i++) {
if(k < s[i]) {
s[i] = k;
for(int j = i + 1; j < s.length; j++) {
s[j] = a[i];
i++;
}
return s;
} else {
s[i] = a[i];
}
}
return s;
}
This method prints out 1, 2, 3, 4, 6, 7, 8, 0, instead of 1, 2, 3, 4, 5, 6, 7, 8.
Change
if(k < s[i]) {
to
if(k < a[i]) {
in line 4.
Actually in the following line you are creating an array with all elements zero:
int[] s = new int[a.length + 1];
s[0] to s[7] will be 0.
Your loop counter i runs from 0 to a.length but the point to note is all the elements of array s will be zero. You are comparing k with s[i] which is zero and for that reason the shifting of arrays never happen (if block never executes).
You need to do two things to fix it.
Initialize element zero of s with the value of a[0].
Compare element with previous element to figure out position to insert.
The final code is:
public static int[] insert(int[] a, int k) {
int[] s = new int[a.length + 1];
s[0] = a[0];
for(int i = 1; i < a.length; i++) {
if(k < s[i-1]) {
s[i] = k;
for(int j = i + 1; j < s.length; j++) {
s[j] = a[i];
i++;
}
return s;
} else {
s[i] = a[i];
}
}
return s;
}
Now you will get:
[1, 2, 3, 4, 6, 5, 7, 8]
I would start by using Arrays.copyOf(int[], int) to create a new array that is one larger than the input. Then iterate that array until I reached the index that the new value belongs at. Then use System.arraycopy(Object,int,Object,int,int) to copy the values into the end of the array. That might look something like
public static int[] insert(int[] a, int k) {
int[] s = Arrays.copyOf(a, a.length + 1);
for (int i = 0; i < s.length; i++) {
if (a[i] < k) {
continue;
}
System.arraycopy(a, i, s, i + 1, s.length - i - 1);
s[i] = k;
break;
}
return s;
}
Which I tested with Arrays.toString(int[]) like
public static void main(String s[]) throws IOException {
int[] array1 = new int[] { 1, 2, 3, 4, 6, 7, 8 };
int[] printArray = insert(array1, 5);
System.out.println(Arrays.toString(printArray));
}
And I get the (expected)
[1, 2, 3, 4, 5, 6, 7, 8]

Move 0's to end of array

I need to move all 0's in an array to the end of the array.
Example: [1, 10, 0, 5, 7] should result in [1, 10, 5, 7, 0].
I am open to doing a reverse loop or a regular loop.
I cannot create a new array.
Here is what I have so far:
for (int i = arr.length; i <= 0; --i) {
if (arr[i] != 0) {
arr[i] = arr.length - 1;
}
}
Thanks!
SIZE(n) where n = arr.size, retain ordering:
Create an array that is the same size as the initial array you need to remove 0s from. Iterate over the original array and add each element to the new array provided it is not 0. When you encounter a 0, count it. Now, when you've reached the end of the first array, simply add the counted number of 0s to the end of the array. And, even simpler, since Java initializes arrays to 0, you can forget about adding the zeroes at the end.
Edit
Since you have added the additional constraint of not being able to create a new array, we need to take a slightly different approach than the one I've suggested above.
SIZE(1)
I assume the array needs to remain in the same order as it was before the 0s were moved to the end. If this is not the case there is another trivial solution as detailed in Brads answer: initialize a "last zero" index to the last element of the array and then iterate backwards swapping any zeros with the index of the last zero which is decremented each time you perform a swap or see a zero.
SIZE(1), retain ordering:
To move the 0s to the end without duplicating the array and keeping the elements in the proper order, you can do exactly as I've suggested without duplicating the array but keeping two indices over the same array.
Start with two indices over the array. Instead of copying the element to the new array if it is not zero, leave it where it is and increment both indices. When you reach a zero, increment only one index. Now, if the two indices are not the same, and you are not looking at a 0, swap current element the location of the index that has fallen behind (due to encountered 0s). In both cases, increment the other index provided the current element is not 0.
It will look something like this:
int max = arr.length;
for (int i = 0, int j = 0; j < max; j++) {
if (arr[j] != 0) {
if (i < j) {
swap(arr, i, j);
}
i++
}
}
Running this on:
{ 1, 2, 0, 0, 0, 3, 4, 0, 5, 0 }
yeilds:
{ 1, 2, 3, 4, 5, 0, 0, 0, 0, 0 }
I made a fully working version for anyone who's curious.
Two choices come to mind
Create a new array of the same size, then Iterate over your current array and only populate the new array with values. Then fill the remaining entries in the new array with "zeros"
Without creating a new array you can iterate over your current array backwards and when you encounter a "zero" swap it with the last element of your array. You'll need to keep a count of the number of "zero" elements swapped so that when you swap for a second time, you swap with the last-1 element, and so forth.
[Edit] 7 years after originally posting to address the "ordering" issue and "last element is zero" issues left in the comments
public class MyClass {
public static void main(String[] args) {
int[] elements = new int[] {1,0,2,0,3,0};
int lastIndex = elements.length-1;
// loop backwards looking for zeroes
for(int i = lastIndex; i >=0; i--) {
if(elements[i] == 0) {
// found a zero, so loop forwards from here
for(int j = i; j < lastIndex; j++) {
if(elements[j+1] == 0 || j == lastIndex) {
// either at the end of the array, or we've run into another zero near the end
break;
}
else {
// bubble up the zero we found one element at a time to push it to the end
int temp = elements[j+1];
elements[j+1] = elements[j];
elements[j] = temp;
}
}
}
}
System.out.println(Arrays.toString(elements));
}
}
Gives you...
[1, 2, 3, 0, 0, 0]
Basic solution is to establish an inductive hypothesis that the subarray can be kept solved. Then extend the subarray by one element and maintain the hypothesis. In that case there are two branches - if next element is zero, do nothing. If next element is non-zero, swap it with the first zero in the row.
Anyway, the solution (in C# though) after this idea is optimized looks like this:
void MoveZeros(int[] a)
{
int i = 0;
for (int j = 0; j < a.Length; j++)
if (a[j] != 0)
a[i++] = a[j];
while (i < a.Length)
a[i++] = 0;
}
There is a bit of thinking that leads to this solution, starting from the inductive solution which can be formally proven correct. If you're interested, the whole analysis is here: Moving Zero Values to the End of the Array
var size = 10;
var elemnts = [0, 0, 1, 4, 5, 0,-1];
var pos = 0;
for (var i = 0; i < elemnts.length; i++) {
if (elemnts[i] != 0) {
elemnts[pos] = elemnts[i];
pos++;
console.log(elemnts[i]);
}
}
for (var i = pos; i < elemnts.length; i++) {
elemnts[pos++] = 0;
console.log(elemnts[pos]);
}
int arrNew[] = new int[arr.length];
int index = 0;
for(int i=0;i<arr.length;i++){
if(arr[i]!=0){
arrNew[index]=arr[i];
index++;
}
}
Since the array of int's is initialized to zero(according to the language spec). this will have the effect you want, and will move everything else up sequentially.
Edit: Based on your edit that you cannot use a new array this answer doesnt cover your requirements. You would instead need to check for a zero(starting at the end of the array and working to the start) and swap with the last element of the array and then decrease the index of your last-nonzero element that you would then swap with next. Ex:
int lastZero = arr.length - 1;
if(arr[i] == 0){
//perform swap and decrement lastZero by 1 I will leave this part up to you
}
/// <summary>
/// From a given array send al zeros to the end (C# solution)
/// </summary>
/// <param name="numbersArray">The array of numbers</param>
/// <returns>Array with zeros at the end</returns>
public static int[] SendZerosToEnd(int[] numbersArray)
{
// Edge case if the array is null or is not long enough then we do
// something in this case we return the same array with no changes
// You can always decide to return an exception as well
if (numbersArray == null ||
numbersArray.Length < 2)
{
return numbersArray;
}
// We keep track of our second pointer and the last element index
int secondIndex = numbersArray.Length - 2,
lastIndex = secondIndex;
for (int i = secondIndex; i >= 0; i--)
{
secondIndex = i;
if (numbersArray[i] == 0)
{
// While our pointer reaches the end or the next element
// is a zero we swap elements
while (secondIndex != lastIndex ||
numbersArray[secondIndex + 1] != 0)
{
numbersArray[secondIndex] = numbersArray[secondIndex + 1];
numbersArray[secondIndex + 1] = 0;
++secondIndex;
}
// This solution is like having two pointers
// Also if we look at the solution you do not pass more than
// 2 times actual array will be resume as O(N) complexity
}
}
// We return the same array with no new one created
return numbersArray;
}
In case if question adds following condition.
Time complexity must be O(n) - You can iterate only once.
Extra
space complexity must be O(1) - You cannot create extra array.
Then following implementation will work fine.
Steps to be followed :
Iterate through array & maintain a count of non-zero elements.
Whenever we encounter a non-zero element put at count location in array & also increase the count.
Once array is iterated completely put the zeros at end of array till the count reach to original length of array.
public static void main(String args[]) {
int[] array = { 1, 0, 3, 0, 0, 4, 0, 6, 0, 9 };
// Maintaining count of non zero elements
int count = -1;
// Iterating through array and copying non zero elements in front of array.
for (int i = 0; i < array.length; i++) {
if (array[i] != 0)
array[++count] = array[i];
}
// Replacing end elements with zero
while (count < array.length - 1)
array[++count] = 0;
for (int i = 0; i < array.length; i++) {
System.out.print(array[i] + " ");
}
}
Time complexity = O(n), Space Complexity = O(1)
import java.util.Scanner;
public class ShiftZeroesToBack {
int[] array;
void shiftZeroes(int[] array) {
int previousK = 0;
int firstTime = 0;
for(int k = 0; k < array.length - 1; k++) {
if(array[k] == 0 && array[k + 1] != 0 && firstTime != 0) {
int temp = array[previousK];
array[previousK] = array[k + 1];
array[k + 1] = temp;
previousK = previousK + 1;
continue;
}
if(array[k] == 0 && array[k + 1] != 0) {
int temp = array[k];
array[k] = array[k + 1];
array[k + 1] = temp;
continue;
}
if(array[k] == 0 && array[k + 1] == 0) {
if(firstTime == 0) {
previousK = k;
firstTime = 1;
}
}
}
}
int[] input(Scanner scanner, int size) {
array = new int[size];
for(int i = 0; i < size; i++) {
array[i] = scanner.nextInt();
}
return array;
}
void print() {
System.out.println();
for(int i = 0; i < array.length; i++) {
System.out.print(array[i] + " ");
}
System.out.println();
}
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
ShiftZeroesToBack sztb = new ShiftZeroesToBack();
System.out.print("Enter Size of Array\t");
int size = scanner.nextInt();
int[] input = sztb.input(scanner, size);
sztb.shiftZeroes(input);
sztb.print();
}
}
let's say we have an array
[5,4,0,0,6,7,0,8,9]
Let's assume we have array elements between 0-100, now our goal is to move all 0's at the end of the array.
now hold 0 from the array and check it with non zero element if any non zero element found swap with that element and so on, at the end of the loop we will find the solution.
here is the code
for (int i = 0; i < outputArr.length; i++)
{
for (int j = i+1; j < outputArr.length; j++)
{
if(outputArr[i]==0 && outputArr[j]!=0){
int temp = outputArr[i];
outputArr[i] = outputArr[j];
outputArr[j] = temp;
}
}
print outputArr[i]....
}
output:
[5,4,6,7,8,9,0,0,0]
Here is how i have implemented this.
Time complexity: O(n) and Space Complexity: O(1)
Below is the code snippet:
int arr[] = {0, 1, 0, 0, 2, 3, 0, 4, 0};
int i=0, k = 0;
int n = sizeof(arr)/sizeof(arr[0]);
for(i = 0; i<n; i++)
{
if(arr[i]==0)
continue;
arr[k++]=arr[i];
}
for(i=k;i<n;i++)
{
arr[i]=0;
}
output: {1, 2, 3, 4, 0, 0, 0, 0, 0}
Explanation: using another variable k to hold index location, non-zero elements are shifted to the front while maintaining the order. After traversing the array, non-zero elements are shifted to the front of array and another loop starting from k is used to override the remaining positions with zeros.
This is my code with 2 for loops:
int [] arr = {0, 4, 2, 0, 0, 1, 0, 1, 5, 0, 9,};
int temp;
for (int i = 0; i < arr.length; i++)
{
if (arr[i] == 0)
{
for (int j = i + 1; j < arr.length; j++)
{
if (arr[j] != 0)
{
temp = arr[j];
arr[j] = arr[i];
arr[i] = temp;
break;
}
}
}
}
System.out.println(Arrays.toString(arr));
output: [4, 2, 1, 1, 5, 9, 0, 0, 0, 0, 0]
public static void main(String[] args) {
Integer a[] = {10,0,0,0,6,0,0,0,70,6,7,8,0,4,0};
int flag = 0;int count =0;
for(int i=0;i<a.length;i++) {
if(a[i]==0 ) {
flag=1;
count++;
}else if(a[i]!=0) {
flag=0;
}
if(flag==0 && count>0 && a[i]!=0) {
a[i-count] = a[i];
a[i]=0;
}
}
}
This is One method of Moving the zeroes to the end of the array.
public class SeparateZeroes1 {
public static void main(String[] args) {
int[] a = {0,1,0,3,0,0,345,12,0,13};
movezeroes(a);
}
static void movezeroes(int[] a) {
int lastNonZeroIndex = 0;
// If the current element is not 0, then we need to
// append it just in front of last non 0 element we found.
for (int i = 0; i < a.length; i++) {
if (a[i] != 0 ) {
a[lastNonZeroIndex++] = a[i];
}
}//for
// We just need to fill remaining array with 0's.
for (int i = lastNonZeroIndex; i < a.length; i++) {
a[i] = 0;
}
System.out.println( lastNonZeroIndex );
System.out.println(Arrays.toString(a));
}
}
This is very simple in Python. We will do it with list comprehension
a =[0,1,0,3,0,0,345,12,0,13]
def fix(a):
return ([x for x in a if x != 0] + [x for x in a if x ==0])
print(fix(a))
int[] nums = { 3, 1, 2, 5, 4, 6, 3, 2, 1, 6, 7, 9, 3, 8, 0, 4, 2, 4, 6, 4 };
List<Integer> list1 = new ArrayList<>();
List<Integer> list2 = new ArrayList<>();
for (int i = 0; i < nums.length; i++) {
if (nums[i] == 3) {
list1.add(nums[i]);
} else if (nums[i] != 3) {
list2.add(nums[i]);
}
}
List<Integer> finalList = new ArrayList<>(list2);
finalList.addAll(list1);
}
}
int[] nums = {3,1,2,5,4,6,3,2,1,6,7,9,3,8,0,4,2,4,6,4};
int i = 0;
for(int j = 0, s = nums.length; j < s;) {
if(nums[j] == 3)
j++;
else {
int temp = nums[i];
nums[i] = nums[j];``
nums[j] = temp;
i ++;
j ++;
}
}
For Integer array it can be as simple as
Integer[] numbers = { 1, 10, 0, 5, 7 };
Arrays.sort(numbers, Comparator.comparing(n -> n == 0));
For int array :
int[] numbers = { 1, 10, 0, 5, 7 };
numbers = IntStream.of(numbers).boxed()
.sorted(Comparator.comparing(n -> n == 0))
.mapToInt(i->i).toArray();
Output of both:
[1, 10, 5, 7, 0]
Lets say, you have an array like
int a[] = {0,3,0,4,5,6,0};
Then you can sort it like,
for(int i=0;i<a.length;i++){
for(int j=i+1;j<a.length;j++){
if(a[i]==0 && a[j]!=0){
a[i]==a[j];
a[j]=0;
}
}
}
public void test1(){
int [] arr = {0,1,0,4,0,3,2};
System.out.println("Lenght of array is " + arr.length);
for(int i=0; i < arr.length; i++){
for(int j=0; j < arr.length - i - 1; j++){
if(arr[j] == 0){
int temp = arr[j];
arr[j] = arr[arr.length - i - 1];
arr[arr.length - i - 1] = temp;
}
}
}
for(int x = 0; x < arr.length; x++){
System.out.println(arr[x]);
}
}
Have a look at this function code:
vector<int> Solution::solve(vector<int> &arr) {
int count = 0;
for (int i = 0; i < arr.size(); i++)
if (arr[i] != 0)
arr[count++] = arr[i];
while (count < arr.size())
arr[count++] = 0;
return arr;
}
import java.io.*;
import java.util.*;
class Solution {
public static int[] moveZerosToEnd(int[] arr) {
int j = 0;
for(int i = 0; i < arr.length; i++) {
if(arr[i] != 0) {
swap(arr, i, j);
j++;
}
}
return arr;
}
private static void swap(int arr[], int i, int j){
int temp = arr[j];
arr[j] = arr[i];
arr[i] = temp;
}
public static void main(String[] args) {
int arr[] =new int[] {1, 10, 0, 2, 8, 3, 0, 0, 6, 4, 0, 5, 7, 0 };
System.out.println(Arrays.toString(moveZerosToEnd(arr)));
}
}
Reimplemented this in Python:
Pythonic way:
lst = [ 1, 2, 0, 0, 0, 3, 4, 0, 5, 0 ]
for i, val in enumerate(lst):
if lst[i] == 0:
lst.pop(i)
lst.append(0)
print("{}".format(lst))
#dcow's implementation in python:
lst = [ 1, 2, 0, 0, 0, 3, 4, 0, 5, 0 ]
i = 0 # init the index value
for j in range(len(lst)): # using the length of list as the range
if lst[j] != 0:
if i < j:
lst[i], lst[j] = lst[j], lst[i] # swap the 2 elems.
i += 1
print("{}".format(lst))
a = [ 1, 2, 0, 0, 0, 3, 4, 0, 5, 0 ]
count = 0
for i in range(len(a)):
if a[i] != 0:
a[count], a[i] = a[i], a[count]
count += 1
print(a)
#op [1, 2, 3, 4, 5, 0, 0, 0, 0, 0]

difficulty with arrays

I am a bit stuck so if anyone has a spare moment it would be a great help for me. I am using eclipse and the program is compiling and running. but there is a runtime error.
in the array {2, 1, 1, 2, 3, 3, 2, 2, 2, 1} I want to print {2, 2, 2} which is the numbers with the highest repeating times in the array. What I am getting is:
0
1
0
0
3
0
2
2
0
Thank you guys and here is my code.
public class SameIndexInArray
{
public static void main(String[] args)
{
int[] array = {2, 1, 1, 2, 3, 3, 2, 2, 2, 1};
int[] subarray = new int[array.length]; //store the values should be {2, 2, 2}
int max = 1;
int total = 1;
for(int i=0; i<array.length-1; i++)
{
if(array[i] != array[i + 1])
{
max = 1;
}
else if(array[i] == array[i + 1])
{
max++;
total = max;
subarray[i] = array[i]; // here is the issue
}
System.out.println(subarray[i]);
}
//System.out.println(total);
}
}
You only store facultatively into subarray, so you should define a separate counter (let's say j) for subarray index counting, and say subarray[j++] = array[i]. And, you shouldn't output subarray for each index of array, so move that println into the second if clause.
see if this works
int[] array = {2, 1, 1, 2, 3, 3, 2, 2, 2, 1};
int frequency = 0;
int num = 0;
for(int i=0; i<array.length-1; i++)
{
int lfreq = 1;
int lnum = array[i];
while(array[i] == array[i+1]){
lfreq++;
i++;
}
if(lfreq >= frequency){
frequency = lfreq;
num = lnum;
}
}
int[] subarray = new int[frequency];
for(int i=0; i < frequency; i++)
subarray[i] = num;
System.out.println(Arrays.toString(subarray));
You need to use another index but "i"
you can't relate to 2 arrays with the same index
Your problem is that all values in subarray are initialized with 0 and you only edit the values when there is an actual sequence, starting with the second element.
The whole subarray is unneccessary. Just save the start index and the length of the subquery ;)
What I mean is something like this:
int[] array = {2, 1, 1, 2, 3, 3, 2, 2, 2, 1};
int startIndex = 0;
int length = 0;
int longestIndex = 0;
int longestLength = 0;
for(int i=0; i<array.length-1; i++)
{
if(array[i] != array[i + 1])
{
if (length > longestLength) {
longestLength = length;
longestIndex = startIndex;
}
startIndex = i;
length = 1;
}
else if(array[i] == array[i + 1])
{
length++;
}
}
if (length > longestLength) {
longestLength = length;
longestIndex = startIndex;
}
Now you that you know where your longest sequence starts and how long it is you can build your new array:
int[] sequence = new int[longestLength];
for (int i = 0; i < longestLength; i++) {
sequence[i] = array[i + startIndex];
}
Thats because you are inserting at an index position "i" into subarray.
For example,
The second time the loop runs.
array[1] == array[2] is true and
subarray[i] = array[i];
runs. So at this moment the contents of subarray is {0,1,0,0,0,0,0,0,0}. Note that arrays are initialized to 0 by default.
This is how you could do it.
int[] array = {2, 1, 1, 2, 3, 3, 2, 2, 2, 1};
//store the values should be {2, 2, 2}
int max = 1;
int total = 1;
int value = 0;
for(int i=0; i<array.length-1; i++)
{
if(array[i] != array[i + 1])
{
max = 1;
}
else if(array[i] == array[i + 1])
{
max++;
total = max;
value = array[i];
}
}
int[] subarray = new int[total];
for(int i=0; i<total; i++)
subarray[i] = value;
public static void main(String[] args) {
int[] ar = { 2, 1, 1, 2, 3, 3, 2, 2, 2, 1 };
int max=0,
maxStart=0,
count=1;
for(int i=1; i<ar.length; i++) {
if (ar[i-1] == ar[i]) {
count++;
if(count > max) {
max = count;
maxStart = i-count+1;
}
}else {
count=1;
}
}
System.out.println("Sub array begins from " + maxStart);
for(int i = maxStart; i < maxStart + max; i++) {
System.out.print(ar[i] + " ");
}
}

Categories

Resources