Move 0's to end of array - java

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]

Related

Merge K sorted arrays of size n using merge algorithm from mergeSort

Problem: Given K sorted arrays of size N each, merge them and print the sorted output.
Sample Input-1:
K = 3, N = 4
arr[][] = { {1, 3, 5, 7},
{2, 4, 6, 8},
{0, 9, 10, 11}} ;
Sample Output-1:
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]
I know there is a way to do this problem using a priority queue/min heap, but I want to do it using the merge procedure from mergeSort. The idea seems straightforward enough...at each iteration, merge the remaining arrays in groups of two, such that the number of arrays gets halved at each iteration.
However, whenever halving leads to an odd number, this becomes problematic.
My idea is that whenever halving leads to an odd number, we take care of the extra array by merging it with the array formed from the last merge.
The code I have so far is below. This only works on one out of 30 test cases, however:
static int[] mergeArrays(int[][] arr) {
int k = arr.length;
int n = arr[0].length;
if(k < 2){
return arr[0];
}
boolean odd_k;
if(k%2){
odd_k = false;
}
else{
odd_k = true;
}
while(k > 1){
int o;
if(odd_k){
o = (k/2) + 1;
}
else{
o = k/2;
}
int[][] out = new int[o][];
for(int i=0; i < k; i = i + 2){
int[] a;
int[] b;
if(odd_k && i == (k-1)){
b = arr[i];
b = out[i-1];
}
else{
a = arr[i];
b = arr[i+1];
}
out[i] = mergeTwo(a, b);
}
k = k/2;
if(k % 2 == 0){
odd_k = false;
}
else{
odd_k = true;
}
arr = out;
}
return arr[0];
}
static int[] mergeTwo(int[] a, int[] b){
int[] c = new int[a.length + b.length];
int i, j, k;
i = j = k = 0;
while(i < a.length && j < b.length){
if(a[i] < b[j]){
c[k] = a[i];
i++;
k++;
}
else{
c[k] = b[j];
j++; k++;
}
}
if(i < a.length){
while(i < a.length){
c[k] = a[i];
i++; k++;
}
}
if(j < b.length){
while(j < b.length){
c[k] = b[j];
j++; k++;
}
}
return c;
}
We can shorten your mergeTwo implementation,
static int[] mergeTwo(int[] a, int[] b) {
int[] c = new int[a.length + b.length];
int i = 0, j = 0, k = 0; // declare and initialize on one line
while (i < a.length && j < b.length) {
if (a[i] <= b[j]) {
c[k++] = a[i++]; // increment and assign
} else {
c[k++] = b[j++]; // increment and assign
}
}
// No need for extra if(s)
while (i < a.length) {
c[k++] = a[i++];
}
while (j < b.length) {
c[k++] = b[j++];
}
return c;
}
And we can then fix your mergeArrays and shorten it by starting with the first row from the int[][] and then using mergeTwo to concatenate the arrays iteratively. Like,
static int[] mergeArrays(int[][] arr) {
int[] t = arr[0];
for (int i = 1; i < arr.length; i++) {
t = mergeTwo(t, arr[i]);
}
return t;
}
I then tested it with
public static void main(String[] args) {
int arr[][] = { { 1, 3, 5, 7 }, { 2, 4, 6, 8 }, { 0, 9, 10, 11 } };
System.out.println(Arrays.toString(mergeArrays(arr)));
}
And I get (as expected)
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]
As you say you have merged two arrays at a time. As it is inefficient you can merge all subarrays same time. What you have to do is to find the minimum from every subarray and remember the position of that element.
To do that we can use another array (say curPos) to remember the current position
private int[] merge(int[][] arr)
{
int K = arr.length;
int N = arr[0].length;
/** array to keep track of non considered positions in subarrays **/
int[] curPos = new int[K];
/** final merged array **/
int[] mergedArray = new int[K * N];
int p = 0;
while (p < K * N)
{
int min = Integer.MAX_VALUE;
int minPos = -1;
/** search for least element **/
for (int i = 0; i < K; i++)
{
if (curPos[i] < N)
{
if (arr[i][curPos[i]] < min)
{
min = arr[i][curPos[i]];
minPos = i;
}
}
}
curPos[minPos]++;
mergedArray[p++] = min;
}
return mergedArray;
Probably the easiest way to handle this is to use a queue of arrays. Initially, add all the arrays to the queue. Then, remove the first two arrays from the queue, merge them, and add the resulting array to the queue. Continue doing that until there is only one array in the queue. Something like:
for each array in list of arrays
queue.push(array)
while queue.length > 1
a1 = queue.pop()
a2 = queue.pop()
a3 = merge(a1, a2)
queue.push(a3)
result = queue.pop()
That simplifies things quite a bit, and the problem of "halving" goes away.

Returning the number of unique numbers in a sorted array [duplicate]

This question already has answers here:
How to efficiently remove duplicates from an array without using Set
(48 answers)
Closed 7 years ago.
I was asked to write a method that accepts a sorted array, removes any duplicate elements found in the array and then places a 0 at the end of the array for every duplicate element found.
It is also supposed to return the number of unique elements found in the array.
Here is my method:
public static int removeDups(int[] arr) {
int j = 0;
int i = 1;
int numDups = 0;
while(i < arr.length) {
if (arr[i] == arr[j]) {
i++;
numDups++;
}
else {
arr[++j] = arr[i++];
}
}
for (int k = j+1; k < arr.length; k++) {
arr[k] = 0;
}
return (j);
}
It successfully finds all the duplicate numbers in the array and places the correct number of 0s at the end, but it doesn't always return the correct value for the number of unique elements.
For example, for the array:
{ 6 10 19 21 23 26 27 36 38 45 }
the number of unique elements should be 10, but it returns 9.
What am I doing wrong?
As it can be seen, j is used as the index of the last unique element.
In an array, i'th index is actually the i + 1'th element counted from 1.
So, you have to return j + 1 instead of j from your method.
Here is a solution to your problem. It keeps track of two pointers, one which only advances when a value gets written to the array, and the other which touches every element of the array in sequential order. When one or more duplicates are encountered, the second pointer keeps advancing, while the first pointer stays put, waiting to write a non-duplicate value. Finally, the code iterates over the remainder of the array from the first pointer, writing out zeroes until the end.
public static int removeDups(int[] arr) {
if (arr == null) {
return null;
}
if (arr.length == 0 || arr.length == 1) {
return arr;
}
int prevIndex = 0;
for (int i=1; i < arr.length; ++i) {
if (arr[prevIndex] != arr[i]) {
arr[prevIndex+1] = arr[i];
++prevIndex;
}
}
for (int i=prevIndex+1; i < arr.length; ++i) {
arr[i] = 0;
}
return prevIndex+1;
}
int[] arr = {1, 2, 3, 3, 4, 5, 6, 6, 6, 10};
removeDups(arr);
System.out.println(Arrays.toString(arr));
Output:
[1, 2, 3, 4, 5, 6, 10, 0, 0, 0]
This code has been tested using IntelliJ and it appears to be working.
Try this!
static int getUniqueElements(int [] sortedArr){
int duplicateCount = 0;
int [] tempArr = sortedArr;
int j=0;
boolean isNewValue = true;
for(int i=1;i<tempArr.length;i++){
if(sortedArr[j] != tempArr[i]){
isNewValue = true;
sortedArr[++j] = tempArr[i];
}else{
if(isNewValue){
isNewValue = false;
duplicateCount++;
}
}
}
for(j++;j<sortedArr.length;j++){
sortedArr[j] = 0;
duplicateCount++;
}
return (sortedArr.length-duplicateCount);
}
public static void main(String[] args) {
int[] arr = {1, 3, 3, 3, 3, 6, 6, 7, 8, 8};
System.out.println("Unique Count:"+ getUniqueElements(arr));
System.out.println(Arrays.toString(arr));
}
OutPut:
Unique Count:2
[1, 3, 6, 7, 8, 0, 0, 0, 0, 0]
Since in the given array 1,7 are unique.
Note: tried with your example array {6, 10, 19, 21, 23 ,26 ,27 ,36 ,38, 45 } also
My solution is as(assuming elements can repeat only twice):
public static int removeDups(int[] arr) {
int i = 0;
int numDups = 0;
while (i < arr.length - 1 - numDups) {
if (arr[i] == arr[i + 1]) {
numDups++;
for (int m = i + 1; m < arr.length - numDups; m++) {
arr[m] = arr[m + 1];
}
arr[arr.length - numDups] = 0;
}
i++;
}
return arr.length-numDups;
}

Java - Sorting out an array

I am encountering some slight and stupid issue while trying to sort out my arrays.
So here's what I'm doing and what I want to do :
I generate an array of ints (good ol' t = new int[];) filled with random generated numbers from -1 to 9. The size of the array is irrelevant. I would like to make so that each "-1" will get to the end of the array while every other will get "pushed" to take the place.
As I'm not a native english speaker it's really hard to express myself correctly on this.
Example :
my array is : 9 2 -1 4 6 -1
I want : 9 2 4 6 -1 -1
I currrently managed to get this BUT it won't work if there are two consecutives -1 cause the second one will get swapped.
Ex :
Initial : 9 2 -1 -1 4 6
After modif : 9 2 -1 4 6 -1
As I said the problem is probably really near from being solved but I really can't find a fix right now.
Here's my code :
for(int i=0;i<NB_CARD;i++)
{
t[i]=randomGenerator.nextInt(10)-1;
System.out.print("t["+i+"]= "+t[i]+"\t\t");
if(i==4){System.out.println("");}
}
//each -1 should be at the end of array
for(int i=0;i<NB_CARD;i++)
{
int tmp=0;
if(t[i]==-1)
{
for(int y=i;y<NB_CARD-1;y++)
{
tmp=t[y+1];
t[y+1]=t[y];
t[y]=tmp;
}
}
}
for(int i=0;i<NB_CARD;i++)
{
System.out.print("t["+i+"]= "+t[i]+"\t\t");
if(i==4){System.out.println("");}
}
Thank you in advance for every tip/help that could lead me to solve this
A more efficient way of doing this with one loop is.
int j = 0;
// copy all the non -1 values down.
for (int i = 0; i < NB_CARD; i++)
if (t[i] != -1)
t[j++] = t[i];
// fill the rest with -1
Arrays.fill(t, j, NB_CARD, -1);
if NB_CARD == t.length you can do
int[] t = {3, -1, -1, -1, 4, 5, 6, -1, -1};
int j = 0;
// copy all the non -1 values down.
for (int i : t)
if (i != -1)
t[j++] = i;
// fill the rest with -1
Arrays.fill(t, j, t.length, -1);
System.out.println(Arrays.toString(t));
prints
[3, 4, 5, 6, -1, -1, -1, -1, -1]
In Java 8 you can do this
int[] t = {6, -1, -1, -1, 4, 5, 3, -1, -1};
List<Integer> sorted = IntStream.of(t).boxed()
.sorted((a, b) -> (a > -1 ? 1 : 0) - (b > -1 ? 1 : 0))
.collect(Collectors.toList());
for (int i = 0; i < t.length; i++)
t[i] = sorted.get(i);
System.out.println(Arrays.toString(t));
which prints
[6, 4, 5, 3, -1, -1, -1, -1, -1]
though it is O(N log N) instead of O(N) and has more code.
I'd use Arrays.sort(T[] a, Comparator c), supplying your own Comparator that puts -1 at the end of the output.
Using bubble sort
package com.appkart.collections;
import java.util.Random;
public class Test {
public void fillRandomNumber(int a[]) {
Random random = new Random();
for (int i = 0; i < a.length; i++) {
a[i] = random.nextInt(10)-1;
}
}
public void printNumber(int a[]) {
for (int i = 0 ; i < a.length ;i++) {
System.out.print(a[i] +" ");
}
}
//Using bubble sort
public void sortRandomNumber(int a[]) {
int length = a.length;
int temp;
for (int i = 0; i < length; i++) {
for (int j = 1; j < length - i; j++) {
if (a[j - 1] < a[j]) {
temp = a[j - 1];
a[j - 1] = a[j];
a[j] = temp;
}
}
}
}
public static void main(String[] args) {
int a[] = new int[10];
Test test = new Test();
test.fillRandomNumber(a);
System.out.println("Random Number bofore sort");
test.printNumber(a);
test.sortRandomNumber(a);
System.out.println("\n Random Number after sort");
test.printNumber(a);
}
}
You can use something like this:
int[] a = { 9, 2, -1, 4, 6, -1 };
for(int i=a.length-1; i>0; i--)
{
for(int j=0; j<i; j++)
{
if(a[i] < a[j])
{
int jvalue = a[j];
a[j] = a[i];
a[i] = jvalue;
}
}
}
If I am understanding the code correctly, if you find a -1, you eventually bubble it up to the end.
What you could do, would be to store the location of the current last element, which at the beginning would be n - 1.
When you find a -1, you could replace the ith element with the current last element and then, decrease the value of current by 1. This should allow you to always put any new -1 elements you encounter at the end.
Code wise:
int[] t = new int[5];
t[0] = -1; t[1] = -1; t[2] = 4;
t[3] = -1; //Just for demonstration purposes
t[4] = -1; //Just for demonstration purposes
int currentLast = 0;
for(int i = t.length - 1; i >=0; i--)
{
if(t[i] == -1)
currentLast = i - 1;
else
break;
}
for(int i = 0; i < t.length; i++)
System.out.println(t[i]);
System.out.println("After");
for(int i = 0; i < currentLast; i++)
{
if(t[i] == -1)
{
int temp = t[currentLast];
t[currentLast] = t[i];
t[i] = temp;
currentLast--;
}
}
for(int i = 0; i < t.length; i++)
System.out.println(t[i]);
}
Yields:
-1
-1
4
-1
-1
After
4
-1
-1
-1
-1
You can convert the array into list, iterate over list and remove all -1, counting how many you removed. Then add that many at the end of the list. If the end result has to be an array, you can use List.toArray method to convert it back.
public static void main(String[] args) {
Integer[] t = {3, -1, -1, -1, 4, 5, 6, -1, -1};
List<Integer> list = new ArrayList<>();
Collections.addAll(list, t);
int numberOfMinusOnes = 0;
for (Integer number : list) {
if (number == -1) {
numberOfMinusOnes++;
}
}
list.removeAll(Arrays.asList(-1));
for (int i = 0; i < numberOfMinusOnes; i++) {
list.add(-1);
}
list.toArray(t);
System.out.println(Arrays.toString(t));
}
Some of boiler plate code can be simplified using google collections library. I would also advise to extract some parts into separate methods to increase readability.

Printing out the least occurring elements in an array

OK, so I found this question from a few days ago but it's on hold and it won't let me post anything on it.
***Note: The values or order in the array are completely random. They should also be able to be negative.
Someone recommended this code and was thumbed up for it, but I don't see how this can solve the problem. If one of the least occurring elements isn't at the BEGINNING of the array then this does not work. This is because the maxCount will be equal to array.length and the results array will ALWAYS take the first element in the code written below.
What ways are there to combat this, using simple java such as below? No hash-maps and whatnot. I've been thinking about it for a while but can't really come up with anything. Maybe using a double array to store the count of a certain number? How would you solve this? Any guidance?
public static void main(String[] args)
{
int[] array = { 1, 2, 3, 3, 2, 2, 4, 4, 5, 4 };
int count = 0;
int maxCount = 10;
int[] results = new int[array.length];
int k = 0; // To keep index in 'results'
// Initializing 'results', so when printing, elements that -1 are not part of the result
// If your array also contains negative numbers, change '-1' to another more appropriate
for (int i = 0; i < results.length; i++) {
results[i] = -1;
}
for (int i = 0; i < array.length; i++) {
for (int j = 0; j < array.length; j++) {
if (array[j] == array[i]) {
count++;
}
}
if (count <= maxCount) { // <= so it admits number with the SAME number of occurrences
maxCount = count;
results[k++] = array[i]; // Add to 'results' and increase counter 'k'
}
count = 0; // Reset 'count'
}
// Printing result
for (int i : results) {
if (i != -1) {
System.out.println("Element: " + i + ", Number of occurences: " + maxCount);
}
}
}
credit to: https://stackoverflow.com/users/2670792/christian
for the code
I can't thumbs up so I'd just like to say here THANKS EVERYONE WHO ANSWERED.
You can also use an oriented object approach.
First create a class Pair :
class Pair {
int val;
int occ;
public Pair(int val){
this.val = val;
this.occ = 1;
}
public void increaseOcc(){
occ++;
}
#Override
public String toString(){
return this.val+"-"+this.occ;
}
}
Now here's the main:
public static void main(String[] args) {
int[] array = { 1,1, 2, 3, 3, 2, 2, 6, 4, 4, 4 ,0};
Arrays.sort(array);
int currentMin = Integer.MAX_VALUE;
int index = 0;
Pair[] minOcc = new Pair[array.length];
minOcc[index] = new Pair(array[0]);
for(int i = 1; i < array.length; i++){
if(array[i-1] == array[i]){
minOcc[index].increaseOcc();
} else {
currentMin = currentMin > minOcc[index].occ ? minOcc[index].occ : currentMin;
minOcc[++index] = new Pair(array[i]);
}
}
for(Pair p : minOcc){
if(p != null && p.occ == currentMin){
System.out.println(p);
}
}
}
Which outputs:
0-1
6-1
Explanation:
First you sort the array of values. Now you iterate through it.
While the current value is equals to the previous, you increment the number of occurences for this value. Otherwise it means that the current value is different. So in this case you create a new Pair with the new value and one occurence.
During the iteration you will keep track of the minimum number of occurences you seen.
Now you can iterate through your array of Pair and check if for each Pair, it's occurence value is equals to the minimum number of occurences you found.
This algorithm runs in O(nlogn) (due to Arrays.sort) instead of O(n²) for your previous version.
This algorithm is recording the values having the least number of occurrences so far (as it's processing) and then printing all of them alongside the value of maxCount (which is the count for the value having the overall smallest number of occurrences).
A quick fix is to record the count for each position and then only print those whose count is equal to the maxCount (which I've renamed minCount):
public static void main(String[] args) {
int[] array = { 5, 1, 2, 2, -1, 1, 5, 4 };
int[] results = new int[array.length];
int minCount = Integer.MAX_VALUE;
for (int i = 0; i < array.length; i++) {
for (int j = 0; j < array.length; j++) {
if (array[j] == array[i]) {
results[i]++;
}
}
if (results[i] <= minCount) {
minCount = results[i];
}
}
for (int i = 0; i < results.length; i++) {
if (results[i] == minCount) {
System.out.println("Element: " + i + ", Number of occurences: "
+ minCount);
}
}
}
Output:
Element: 4, Number of occurences: 1
Element: 7, Number of occurences: 1
This version is also quite a bit cleaner and removes a bunch of unnecessary variables.
This is not as elegant as Iwburks answer, but I was just playing around with a 2D array and came up with this:
public static void main(String[] args)
{
int[] array = { 3, 3, 3, 2, 2, -4, 4, 5, 4 };
int count = 0;
int maxCount = Integer.MAX_VALUE;
int[][] results = new int[array.length][];
int k = 0; // To keep index in 'results'
for (int i = 0; i < array.length; i++) {
for (int j = 0; j < array.length; j++) {
if (array[j] == array[i]) {
count++;
}
}
if (count <= maxCount) {
maxCount = count;
results[k++] = new int[]{array[i], count};
}
count = 0; // Reset 'count'
}
// Printing result
for (int h = 0; h < results.length; h++) {
if (results[h] != null && results[h][1] == maxCount ) {
System.out.println("Element: " + results[h][0] + ", Number of occurences: " + maxCount);
}
}
Prints
Element: -4, Number of occurences: 1
Element: 5, Number of occurences: 1
In your example above, it looks like you are only using ints. I would suggest the following solution in that situation. This will find the last number in the array with the least occurrences. I assume you don't want an object-oriented approach either.
int [] array = { 5, 1, 2, 40, 2, -1, 3, 2, 5, 4, 2, 40, 2, 1, 4 };
//initialize this array to store each number and a count after it so it must be at least twice the size of the original array
int [] countArray = new int [array.length * 2];
//this placeholder is used to check off integers that have been counted already
int placeholder = Integer.MAX_VALUE;
int countArrayIndex = -2;
for(int i = 0; i < array.length; i++)
{
int currentNum = array[i];
//do not process placeholders
if(currentNum == placeholder){
continue;
}
countArrayIndex = countArrayIndex + 2;
countArray[countArrayIndex] = currentNum;
int count = 1; //we know there is at least one occurence of this number
//loop through each preceding number
for(int j = i + 1; j < array.length; j++)
{
if(currentNum == array[j])
{
count = count + 1;
//we want to make sure this number will not be counted again
array[j] = placeholder;
}
}
countArray[countArrayIndex + 1] = count;
}
//In the code below, we loop through inspecting each number and it's respected count to determine which one occurred least
//We choose Integer.MAX_VALUE because it's a number that easily indicates an error
//We did not choose -1 or 0 because these could be actual numbers in the array
int minNumber = Integer.MAX_VALUE; //actual number that occurred minimum amount of times
int minCount = Integer.MAX_VALUE; //actual amount of times the number occurred
for(int i = 0; i <= countArrayIndex; i = i + 2)
{
if(countArray[i+1] <= minCount){
minNumber = countArray[i];
minCount = countArray[i+1];
}
}
System.out.println("The number that occurred least was " + minNumber + ". It occured only " + minCount + " time(s).");

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