Shift all zeros in 2d matrix - java

I have a 2d array like this:
2 0 0 2 0 4
2 0 0 2 0 4
2 0 0 2 0 4
And I want to shift all the zeros to the left, so for that I made this method:
public static void shiftLeft(int [][] array){
for (int j = 0; j < array.length; j++) {
for (int i = 0; i < array.length - 1; i++) {
if ((array[j][i] != 0) && (array[j][i + 1] == 0)) {
array[j][i + 1] = array[j][i];
array[j][i] = 0;
}
}
}
}
But the output I get is this:
0 0 2 0 2 4
0 0 2 0 2 4
0 0 2 0 2 4
How can I make all zeros to go to the left?

In my opinion the easiest way to do this is using 3 nested loops.
Variable i iterates over the rows.
Variable j1 finds the first nonzero element starting from the left of each row.
Variable j2 finds the first zero element after j1 and swaps them.
The code below assumes that the bidimensional matrix A was declared as A[N][M], where N and M are respectively the number of rows and number of columns.
for(int i =0;i<N;i++){
for(int j1=0;j1<M;j1++){
if (A[i][j1]==0)
continue;
for(int j2=j1;j2<M;j2++){
if( A[i][j2]==0){
//swap
int tmp=A[i][j1];
A[i][j1]=A[i][j2];
A[i][j2]=tmp;
}
}
}
}

In fact Trugis's answer is also correct but it will just swap the zero with the first non zero. So the order of the numbers will change.
This answer will not change the order of the numbers :
int[][] A = { { 2, 3, 4, 2, 4, 4, 5, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 4, 3, 4, 5, 6 },
{ 2, 0, 4, 2, 0, 4, 1, 2, 3, 4 }};
int N = A.length;
int M = A[0].length;
int firstZeros = 0;
for(int i = 0; i < N; i++) { // Loop over the rows
for(int j1 = 0; j1 < M; j1++) {
// If there is a zero we pass by
if (A[i][j1] == 0 && firstZeros == j1) {
firstZeros++;
continue;
}
// Otherwise, we have a value so we want to check if there is a zero afterwards
for(int j2 = j1+1; j2 < M; j2++) {
// If we find a zero we move it to the left
if(A[i][j2] == 0) {
for (int j3 = j2; j3 > firstZeros; j3--) {
// Change zero with previous value
A[i][j3] = A[i][j3-1];
A[i][j3-1] = 0;
}
firstZeros++;
}
}
}
firstZeros = 0;
}

Related

Duplicate zero in array by modifying the array in place

There is a fixed length array arr of integers, duplicate each occurrence of zero, shifting the remaining elements to the right. The elements beyond the length of the original array are not written.
We have to modify input array in place and doesn't have to create new array.
So I created that but it is duplicating the zero which is at the end of array and not the previous zeros. Can somebody help me with this?
public static void addPos() {
int arr[] = { 1, 2, 0, 3, 0, 5, 0, 7, 8 };
int result[] = new int[arr.length];
for (int i = 0; i < arr.length; i++) {
if (arr[i] == 0) {
int loc = i;
for (int j = 0; j < loc; j++) {
result[j] = arr[j];
result[loc] = 0;
}
for (int j = loc + 1; j < arr.length; j++) {
result[j] = arr[j - 1];
}
}
}
for (int k = 0; k < arr.length; k++)
System.out.println(result[k]);
}
Output
1
2
0
3
0
5
0
0
7
Expected output:
1
2
0
0
3
0
0
5
0
Every iteration of the loop overwrites the results from the previous iteration, so the end result only shows the results from the last iteration, which duplicates the last 0 is duplicated.
One way to solve this is by iterating backwards "right to left". It simplifies a lot of things. You can get rid of the auxiliary result array. The basic idea is, go backwards in the array, and every time you find a 0, you duplicate it by rewriting the array to the right of the zero.
public static void addPos() {
int arr[] = {1, 2, 0, 3, 0, 5, 0, 7, 8};
for (int i = arr.length - 1; i >= 0; i--) {
if (arr[i] == 0) {
// duplicate it!
for (int j = arr.length - 1; j > i; j--) {
arr[j] = arr[j-1];
}
}
}
for (int k = 0; k < arr.length; k++) {
System.out.println(arr[k]);
}
}
The for loop keeps overwriting the values in result array, hence the result shows only last duplication.You should not be using the result array at all.Keep shipting values in the original array itself.
You can refer to below code.
for(int i=0;i<arr.length-1;i++){
if(arr[i]==0){
for(int j=arr.length-1;j>i;j--){
arr[j]=arr[j-1];
}
i++;
}
}
public void duplicateZeros(int[] arr)
{
int i=0;
while(i<arr.length)
{
if(arr[i]==0)
{
int j=arr.length-1;
while(j != i)
{
arr[j]=arr[j-1];
j--;
}
i=i+2;
}
else
{
i=i+1;
}
}
}
Without using any other Array.
class Solution {
public void duplicateZeros(int[] arr) {
for(int i=0;i<arr.length;i++){
if(arr[i]==0){
for(int j=arr.length-1;j>i;j--){
arr[j]=arr[j-1];
}
i=i+1;
}
}
}
}
So one has this:
int[] arr = { 1, 2, 0, 3, 0, 5, 0, 7, 8 };
public static void duplicateZeros(int[] arr) {
and should get
{ 1, 2, 0, 3, 0, 5, 0, 7, 8 }
v___
{ 1, 2, 0, 0, 3, 0, 5, 0, 7 }
v___
{ 1, 2, 0, 0, 3, 0, 0, 5, 0 }
This looks like:
for (int i = 1; i < n; ++i) {
if (arr[i - 1] == 0) {
insert at i a 0;
}
}
insert at i a 0:
// First move the remaining to the right: i .. n-2
...
// Then fill in the zero
arr[i] = 0;
Python solution for anyone interested adapted from here
the solution is non-trivial if you do not separate the action of the pointer iterating over the list and the insertions. It's very easy to write a for-loop that adds 0's ad-infinitum.
def duplicateZeros(arr):
# define the incrementor
i = 0
# loop through all dynamic elements
while i < len(arr)-1:
# if the character is a zero
if arr[i]==0:
# remove the last item from the array
arr.pop()
# insert a zero in front of current element
arr.insert(i+1, 0)
# move one place forward
i += 1
# increment to the next character
i += 1
Solution 1: Loop from start to end. If zero is found, move the elements from next index and fill the next as zero and skip next.
public static void duplicateZeros(int[] arr) {
System.out.println("BEGIN duplicateZeros:" + Arrays.toString(arr));
for(int i=0; i<arr.length-1; ++i) {
if (arr[i] == 0) {
move(arr, i);
++i;
}
}
System.out.println("END duplicateZeros:" + Arrays.toString(arr) +"\n");
}
private static void move(int[] arr, int index) {
// move to the right from index+1
for(int i=arr.length-1; i>index; i--) {
arr[i] = arr[i-1];
}
// fill 0 at index
arr[index] = 0 ;
}
Solution2: Loop from end to start. If zero is found, move the elements from next index and fill the current index as zero.
public static void duplicateZeros(int[] arr) {
System.out.println("BEGIN duplicateZeros:" + Arrays.toString(arr));
for(int i=arr.length-1; i>=0; i--) {
if (arr[i] == 0) {
move(arr, i);
}
}
System.out.println("END duplicateZeros:" + Arrays.toString(arr) +"\n");
}
private static void move(int[] arr, int index) {
// move to the right from index+1
for(int i=arr.length-1; i>index; i--) {
arr[i] = arr[i-1];
}
// fill 0 at index
arr[index] = 0 ;
}
class Solution:
def duplicateZeros(self, arr: List[int]) -> None:
"""
Do not return anything, modify arr in-place instead.
"""
if len(arr)==0:
return arr
index = 0
while index < len(arr):
print(index,end=" ")
if arr[index]==0:
arr.insert(index+1,0)
arr.pop()
index+=1
index+=1

Java - How to Modify Arrays Separately When Using a Multidimensional Array?

I have a multi-dimensional array made of two separate arrays.
// slot1 = new int[][] { {Array1}, {Array2}}
slot1 = new int[][] { {1, 2 ,3}, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } };
I'm trying to do two separate things.
I'm trying to print the contents of array slot1 , but with a space between each array. For example, I want my output to be something like:
1 2 3 ----- 0 0 0 0 0 0 0 0 0 0 0 0 0 0
Note: where I have the dashes, I'll actually be adding a space
I want to know how I would modify the values of each internal array separately?
For example, how would I change the value of index 5 in Array2? And add value 1? So that if I print slot1 array, my values should look like this?
1 2 3 ----- 0 0 0 0 0 1 0 0 0 0 0 0 0 0
I have looked other questions related to this, but I haven't found a clear answer when working two a 2D array made of other arrays? Would ArrayList work best for this type of scenario?
Here is my complete Code
public class Sandbox {
static int[][] slot1;
public static void main(String[] args) {
Sandbox.setCache();
Sandbox.displayCache();
}
public static void setCache() {
slot1 = new int[][] { { 1, 2 ,3}, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } };
}
public static void displayCache() {
for (int i = 0; i < slot1.length; i++) {
for (int j = 0; j < slot1[i].length; j++) {
System.out.print(slot1[i][j] + " "); // How to add a space between i and j?
}
}
}
}
I will assume that this is a beginner question.
To put spaces between the two arrays in slot1 you can proceed in this simple way:
public static void displayCache() {
for (int i = 0; i < slot1.length; i++) {
for (int j = 0; j < slot1[i].length; j++) {
System.out.print(slot1[i][j] + " ");
}
System.out.print(" "); //Add spaces here using your preferred way
}
}
But, you'd probably doesn't want the spaces after the last array, so this is another (better) way:
public static void displayCache() {
if(slot1.length > 0) {
for (int j = 0; j < slot1[0].length; j++)
System.out.print(slot1[0][j] + " ");
for (int i = 1; i < slot1.length; i++) { //Note: now i = 1
System.out.print(" "); //Add spaces here using your preferred way
for (int j = 0; j < slot1[i].length; j++)
System.out.print(slot1[i][j] + " ");
}
}
}
To remove the space at the end of each array last element, you can apply the same logic (this is a work for you).
To change a value in slot1 (using your example as example) you can do this:
slot1[1][5] = 1;

Test Cases fail to satisfy

I'm just a beginner. I came across this question for which my code fails to satisfy all/most of the test cases.
Question:
Given an array of numbers, find the number of non-empty sub-arrays in which the minimum and maximum element are identical.
Example:
Input: Array = [1, 1, 3]
Output: 4
Explanation:
The required sub-arrays are [1], [1], [3], [1,1]
My solution:
Sort the array and solve the problem.
Code:
for(int i = 0; i < testCases; i++){
int arraySize = in.nextInt();
int array[] = new int[arraySize];
for(int j = 0; j < arraySize; j++){
array[j] = in.nextInt();
}
temp[i] = (findSubArrays(array));
}
for(int i = 0; i < testCases; i++){
System.out.println(temp[i]);
}
private static int findSubArrays(int[] array) {
Arrays.sort(array);
//Since each element can form a sub-array of its own
int noOfSubArrays = array.length;
for(int i = 0; i < array.length-1; i++){
if(array[i] == array[i+1]){
noOfSubArrays++;
}
}
return noOfSubArrays;
}
So you're sorting the array to keep begin points and end points adjacent so you don't need a nested traversal. That makes sense. The problem is that you're counting adjacent duplicates, but what you really need is T(n), or the triangle number of consecutive duplicates. Consider a simple scenario:
[1, 1, 1]
Your algorithm returns 5, but there are actually 6 subsets (by start & end index):
0, 0
0, 1
0, 2
1, 1
1, 2
2, 2
So let's update the algorithm to calculate the triangle number of each sequence:
private static int findSubArrays(int... array) {
Arrays.sort(array);
int sequenceCount = 0;
int total = 0;
for (int i = 0; i < array.length + 1; i++) {
if (i == array.length || (i > 0 && array[i] != array[i - 1])) {
total += triangle(sequenceCount);
sequenceCount = 0;
}
sequenceCount++;
}
return total;
}
private static int triangle(int n) {
return (n * (n + 1)) / 2;
}
Now calling findSubArrays(1, 1, 1) returns 6 and findSubArrays(1, 1, 3) returns 4.

Java - 2D Array Board Counter

I have a homework question that I have trouble debugging. The purpose of the program is to state which rows and columns have the same numbers, as well as major and minor diagonals. So far I have kind of figured out the rows and columns that are the same, and printing them.
Here is the output of the program thus far:
0 0 0 0 0 0 0 0
0 0 1 0 1 0 0 0
0 0 0 0 1 0 1 0
0 0 1 0 0 1 1 0
0 0 1 0 0 1 1 0
0 0 0 0 0 0 1 0
0 0 0 0 0 0 0 0
0 0 1 1 1 1 1 0
All 0 on row 0
All 0 on column 0
All 0 on column 1
All 0 on column 1
All 0 on column 7
All 0 on column 7
As you can see the column print is repeated, and I can't figure out why and how to fix it. I also have a problem in which it is not displaying row 6 as being all the same.
My desired output should be:
All 0 on row 0
All 0 on row 6
All 0 on column 0
All 0 on column 1
All 0 on column 7
Thank you in advance.
import java.util.Scanner;
public class javaTest
{
// Main method
public static void main(String[] args)
{
int[][] array = {
{0,0,0,0,0,0,0,0},
{0,0,1,0,1,0,0,0},
{0,0,0,0,1,0,1,0},
{0,0,1,0,0,1,1,0},
{0,0,1,0,0,1,1,0},
{0,0,0,0,0,0,1,0},
{0,0,0,0,0,0,0,0},
{0,0,1,1,1,1,1,0}
};
for(int i = 0; i < array.length; i++)
{
for(int j = 0; j < array[i].length; j++)
System.out.print(array[i][j] + " ");
System.out.println();
}
checkRow(array);
checkCol(array);
}
// Check if the row is the same
public static void checkRow(int array[][])
{
String checkRow = "";
int rowCount = 0;
int count = 0;
for(int i = 0; i < array.length; i++)
{
for(int j = 0; j < array[i].length;j++)
{
// Create a new array to compare
int num = array[i][j];
for(int k = 0; k < array[i].length; k++)
{
// Check if the first number of the row is equal to the next
if(num == array[j][k])
// If so increment count
count++;
else
count = 0;
}
// If all numbers of the row is the same, total would be 8 and print
if(count == array.length)
System.out.println("All " + num + " on row " + rowCount);
}
rowCount++;
}
}
// Check if column is the same
public static void checkCol(int array[][])
{
String checkCol = "";
int colCount = 0;
int count = 0;
for(int i = 0; i < array.length; i++)
{
for(int j = 0; j < array[i].length; j++)
{
int num = array[i][j];
for(int k = 0; k < array[i].length; k++)
{
if(num == array[k][i])
count++;
else
count = 0;
}
if(count == array.length)
System.out.println("All " + num + " on column " + colCount);
}
colCount++;
}
}
}
I don't think you need 3 nested for loop in your checkRow or checkCol methods. I'll explain how you could it with just 2 for methods for checkCol.
You would still have your outer 2 for loops
i going from 0 to array.length - 1
j going from 0 to array[i].length - 1
Then inside this for loop, you check if every element at array[i][j] is equal to array[0][j] (which is the element at the 0th row for that particular column).
Maintain a boolean flag that you set to false if any of the elements in a particular column is not equal to the element at the 0th row of the column. Make sure this flag is set to true before you even enter the for loop.
Outside of the inner for loop, you check if the flag is set to true, if so print that particular column and number. Reset the flag to true.
I think this would probably fix up the issue of printing columns multiple times. You could do something similar for the rows as well.
Let me know if you don't understand any of the steps.
I believe that this is your problem
if(count == array.length)
System.out.println("All " + num + " on row " + rowCount);
}
rowCount++;// this is inside the first for loop but not the second. so it has to go through all the other inner for loops before it can count this again so its skipping rows
This problem can be solved using two for-loops, as suggested by #maesydy. Here is the implementation with output.
public class Test {
// Main method
public static void main(String[] args) {
int[][] array = {
{0, 0, 0, 0, 0, 0, 0, 0},
{0, 0, 1, 0, 1, 0, 0, 0},
{0, 0, 0, 0, 1, 0, 1, 0},
{0, 0, 1, 0, 0, 1, 1, 0},
{0, 0, 1, 0, 0, 1, 1, 0},
{0, 0, 0, 0, 0, 0, 1, 0},
{0, 0, 0, 0, 0, 0, 0, 0},
{0, 0, 1, 1, 1, 1, 1, 0}
};
for (int i = 0; i < array.length; i++) {
for (int j = 0; j < array[i].length; j++)
System.out.print(array[i][j] + " ");
System.out.println();
}
checkRow(array);
checkCol(array);
}
/**
* Check if all elements of row are same
* #param a array
*/
public static void checkRow(int a[][]) {
for (int r= 0; r < a.length; r++) {
int rowNum = r + 1;
boolean isMatching = true;
for (int c = 0; c < a[r].length -1; c++) {
//Compare two subsequent columns in same column
if(a[r][c] != a[r][c+1]) {
isMatching = false;
break;
}
}
//If all elements matched print output
if(isMatching) {
System.out.println("Row " + rowNum + " has all matching elements");
}
}
}
/**
* Check if all elements of column are same
* #param a array
*/
public static void checkCol(int a[][]) {
for (int c = 0; c < a.length; c++) {
int colNum = c + 1;
boolean isMatching = true;
for (int r = 0; r < a[c].length -1; r++) {
//Compare two subsequent rows in same column
if(a[r][c] != a[r+1][c]) {
isMatching = false;
break;
}
}
//If all elements matched print output
if(isMatching) {
System.out.println("Column " + colNum + " has all matching elements");
}
}
}
}
Notes: I have used indexes named r/c to depict row and column index.
Output:
0 0 0 0 0 0 0 0
0 0 1 0 1 0 0 0
0 0 0 0 1 0 1 0
0 0 1 0 0 1 1 0
0 0 1 0 0 1 1 0
0 0 0 0 0 0 1 0
0 0 0 0 0 0 0 0
0 0 1 1 1 1 1 0
Row 1 has all matching elements
Row 7 has all matching elements
Column 1 has all matching elements
Column 2 has all matching elements
Column 8 has all matching elements
Hope this helps. Happy programming, enjoy!

Sort Java array while adding numbers

I apologize for my english. So far I got this code that sort an array. The user input 10 numbers and after that, the program makes the sorting. But what I want is that every time the user inputs a number, the program immediately makes the sort. How can I do that?
For example, if I input 5 and then 3, immediately takes the 3 to the first position. And then if I put 2, immediately take it to the first position and sort the others (2,3,5). Then if I put 1, takes it to the first position, sorting the others(1,2,3,5) and so on.
import java.util.Scanner;
public class Nine{
public static void main(String[] args){
Scanner input = new Scanner(System.in);
int temp = 0;
int[] num = new int[10];
for(int i = 0; i < 10; i++){
System.out.print("Número: ");
num[i] = input.nextInt();
}
System.out.println();
for(int i = 0; i < 10; i++){
System.out.print(num[i] + " ");
}
System.out.println();
for(int i = 0; i < 10; i++){
for(int j = 0; j < 10 - i - 1; j++){
if(num[j+1] < num[j]){
temp = num[j+1];
num[j+1] = num[j];
num[j] = temp;
}
}
}
System.out.println();
for(int i = 0; i < 10; i++){
System.out.print(num[i] + " ");
}
}
}
Now I have this code and it works. It does what I wanted to do. But to me it's a little bit complicated. I'm still a beginner. I understand what it does but is there a better way to do it. An easier way? Thanks
import java.util.Scanner;
public class practice {
public static void main(String[] args){
Scanner input = new Scanner(System.in);
int[] num = new int[10];
int n = 0, l = 0, t = 0;
for(int i = 0; i < num.length; i++){
System.out.print("Número: ");
n = input.nextInt();
l = 0;
while(num[l] < n && l < i){
l = l + 1;
}
t = i;
while(t > l){
num[t] = num[t - 1];
t = t - 1;
}
num[l] = n;
for(int temp : num){
System.out.print(temp + " ");
}
System.out.println();
}
}
}
here you go
public class TestProgram {
public static void main(String args[]) {
Scanner input = new Scanner(System.in);
int temp = 0;
int[] num = new int[10];
for (int b = 0; b < 10; b++) {
System.out.println("Número: ");
num[b] = input.nextInt();
for (int i = 0; i < 10; i++) {
for (int j = 0; j < 10 - i - 1; j++) {
if (num[j + 1] < num[j]) {
temp = num[j + 1];
num[j + 1] = num[j];
num[j] = temp;
}
}
}
System.out.println();
for (int k = 0; k < 10; k++) {
System.out.println(num[k] + " ");
}
}
}
}
To do this create a sort method which you can call to sort an array then return a new sorted array. Next every time a user inputs run a for loop which will create an array with the current amount entered. While entering just use i+1. Finally, with the new array call the sort method and the sorted array will be returned and you can do as you wish with the new array.
You make things more difficult for yourself using an array but assuming you want to start with an array of size 10 filled with 0s (so 0 is not a valid input) the basic algorithm is to go through the currently sorted array and if the current value is less than the indexed value move all the values in the sorted array to the right and insert the current value at the current index. As others have already mentioned for larger datasets this is very inefficient but for an array of size 10 it's not a big deal.
int current = input.nextInt();
for (int j = 0; j < sorted.length; j++) {
if (sorted[j] == 0) {
sorted[j] = current;
break;
}
if (current < sorted[j]) {
for (int k = sorted.length - 1; k > j; k--) {
sorted[k] = sorted[k - 1];
}
sorted[j] = current;
break;
}
}
Here's what the output at each iteration would look like for the input 5, 3, 2, 1, 4, 10, 20, 15, 13, 5:
5 0 0 0 0 0 0 0 0 0
3 5 0 0 0 0 0 0 0 0
2 3 5 0 0 0 0 0 0 0
1 2 3 5 0 0 0 0 0 0
1 2 3 4 5 0 0 0 0 0
1 2 3 4 5 10 0 0 0 0
1 2 3 4 5 10 20 0 0 0
1 2 3 4 5 10 15 20 0 0
1 2 3 4 5 10 13 15 20 0
1 2 3 4 5 5 10 13 15 20

Categories