How can I find three of the same numbers in a row? - java

I have an array something like the following.
int[][] myArray =
{{1, 2, 3, 0, 0, 1}
{1, 0, 4, 4, 0, 1}
{1, 2, 4, 3, 4, 0}
{2, 2, 0, 0, 2, 2}
{3, 0, 0, 3, 0, 0}
{4, 2, 3, 0, 0, 0}}
It would say that one had won because of the 1s in the three 1s in the first column. Two would not win because they are not in a "row".
I want to do some sort of win checking so that it finds three of the same number in a row, diagonal or column. Sort of like tic-tac-toe but with a larger grid. Before I used a messy set of if statements and goto statements. (It was written in Basic.) I have tried using a system where it found the directions from the last placed piece, in which there is a number of the same, but it didn't work properly. How can I do this in an easy and maintainable way?
Tried code:
private static boolean checkBoardCombinations(int[][] board, int inputX, int inputY) {
int currentPlayer = board[inputX-1][inputY-1];
boolean[][] directions = new boolean[3][3];
for(int y = 0; y >= -2; y--){
for(int x = 0; x >= -2; x--){
if(inputX+x >= 0 && inputX+x <= 7 && inputY+y >= 0 && inputY+y <= 7
&& (board[inputX+x][inputY+y] == currentPlayer)){
//System.out.printf("X: %s Y: %s", inputX+x, inputY+y);
directions[x+2][y+2] = true;
}
else{
directions[x+2][y+2] = false;
}
//System.out.printf("X: %s Y: %s B: %s,", inputX+x, inputY+y, directions[x+2][y+2]);
}
//System.out.println();
}
/*
for(int x = 0; x <= 2; x++){
for(int y = 0; y <= 2; y++){
System.out.print(directions[x][y] + " ");
}
System.out.println();
}
*/
return false;
}

Supposing the number of players are known, you can iterate over all the players one by one, and check if any player is forming a connection of required length or not.
Such code would look like following:
private int[][] grid; // Your array of size ROWS x COLUMNS
private final int ROWS = 6, COLUMNS = 6;
private final int CONSECUTIVE_CONNECTION_REQUIRED = 3;
// Returns true if given playerType is forming a connection, else false.
public boolean checkGrid(int playerType)
{
// Check downward
for (int i = 0; i <= ROWS - CONSECUTIVE_CONNECTION_REQUIRED; i++)
{
for (int j = 0; j < COLUMNS; j++)
{
int counter = 0;
for (int k = i; k < CONSECUTIVE_CONNECTION_REQUIRED + i; k++)
{
if (grid[k][j] == playerType)
counter++;
}
if (counter == CONSECUTIVE_CONNECTION_REQUIRED)
return true;
}
}
// Check across
for (int i = 0; i <= COLUMNS - CONSECUTIVE_CONNECTION_REQUIRED; i++)
{
for (int j = 0; j < ROWS; j++)
{
int counter = 0;
for (int k = i; k < CONSECUTIVE_CONNECTION_REQUIRED + i; k++)
{
if (grid[j][k] == playerType)
counter++;
}
if (counter == CONSECUTIVE_CONNECTION_REQUIRED)
return true;
}
}
// Check left to right diagonally
for (int i = 0; i <= ROWS - CONSECUTIVE_CONNECTION_REQUIRED; i++)
{
for (int j = 0; j <= COLUMNS - CONSECUTIVE_CONNECTION_REQUIRED; j++)
{
int counter = 0;
for (int k = i, m = j; k < CONSECUTIVE_CONNECTION_REQUIRED + i; k++, m++)
{
if (grid[k][m] == playerType)
counter++;
}
if (counter == CONSECUTIVE_CONNECTION_REQUIRED)
return true;
}
}
// Check right to left diagonally
for (int i = 0; i <= ROWS - CONSECUTIVE_CONNECTION_REQUIRED; i++)
{
for (int j = COLUMNS - 1; j >= COLUMNS - CONSECUTIVE_CONNECTION_REQUIRED; j--)
{
int counter = 0;
for (int k = i, m = j; k < CONSECUTIVE_CONNECTION_REQUIRED + i; k++, m--)
{
if (grid[k][m] == playerType)
counter++;
}
if (counter == CONSECUTIVE_CONNECTION_REQUIRED)
return true;
}
}
return false;
}
Where playerType is 0, 1, 2, 3 and so on...
You can use checkGrid() method like following:
for(int i = MIN_PLAYER_NUMBER; i <= MAX_PLAYER_NUMBER; i++)
{
if(checkGrid(i))
{
// Player i is forming the connection!!!
}
}
But if you don't want to iterate over your grid this many times, then drop your two dimensional array, and use a graph with adjacency list representation. Write a proper API for that which lets you make changes in your particular representation easily, and you can then find if any player is making a connection of particular length in the graph or not, in less iterations.

Although you already accepted an answer I thought to also submit you my answer for diversity :)
public static void main (String[] args)
{
int[][] myArray =
{{1, 2, 3, 0, 0, 1},
{1, 0, 4, 4, 0, 1},
{1, 2, 4, 3, 4, 0},
{2, 2, 0, 0, 2, 2},
{3, 0, 0, 3, 0, 0},
{4, 2, 3, 0, 0, 0}};
System.out.println(testForWinner(myArray));
}
/**
* Returns -1 if no winner
*/
static int testForWinner(int[][] ar) {
for(int i=0; i<ar.length; i++) {
for(int j=0; j<ar[i].length; j++) {
if(checkNext(ar, i, j, 0, 1, 1)) { //Check the element in the next column
return ar[i][j];
}
for(int k=-1; k<=1; k++) { //Check the three adjacent elements in the next row
if(checkNext(ar, i, j, 1, k, 1)) {
return ar[i][j];
}
}
}
}
return -1;
}
/**
* Step number `step` starting at `ar[i][j]` in direction `(di, dj)`.
* If we made 3 steps we have a winner
*/
static boolean checkNext(int[][] ar, int i, int j, int di, int dj, int step) {
if(step==3) {
return true;
}
if(i+di<0 || i+di>ar.length-1 || j+dj<0 || j+dj>ar[i].length-1) {
return false;
}
if(ar[i+di][j+dj]==ar[i][j]) {
return checkNext(ar, i+di, j+dj, di, dj, step+1);
}
return false;
}
See it in action: http://ideone.com/Ou2sRh

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.

How to rotate an array right

I have wrote a program to shift an int array left, but cannot find a way to move it right. Could you take a look at my code and comment if you have any ideas how how to "rotate" my array right based on the number of spaces (int x), as currently it only moves left. Thanks
public void makeRight(int x) {
int[] anArray = {0, 1, 2, 3, 4, 5};
int counter = 0;
while (counter < x) {
int temp = anArray[0];
for (int i = 0; i < anArray.length - 1; i++) {
anArray[i] = anArray[i + 1];
}
anArray[anArray.length - 1] = temp;
counter++;
}
for (int i = 0; i < anArray.length; i++){
System.out.print(anArray[i] + " ");
}
}
Rotate an array right
public void makeRight( int x )
{
int[] anArray =
{ 0, 1, 2, 3, 4, 5 };
int counter = 0;
while ( counter < x )
{
int temp = anArray[anArray.length - 1];
for ( int i = anArray.length - 1; i > 0; i-- )
{
anArray[i] = anArray[i - 1];
}
anArray[0] = temp;
counter++;
}
for ( int i = 0; i < anArray.length; i++ )
{
System.out.print( anArray[i] + " " );
}
}
while (counter < x) {
int temp = anArray[anArray.length - 1];
for (int i = anArray.length - 1; i > 0; i--) {
anArray[i] = anArray[i - 1];
}
anArray[0] = temp;
counter++;
}
in my opinion basically you had done on most of the parts to rotate an array (right).
Just that the concept of
anArray[i] = secondArray[(i + x) % anArray.length];
And
anArray[(i + x) % anArray.length] = secondArray[i];
is a bit different.
There would be something like this
int[] anArray = {0, 1, 2, 3, 4, 5};
//int counter = 0;
//int x = 2;
int[] secondArray = new int[anArray.length];
for (int i = 0; i < anArray.length; i++) {
secondArray[(i + x) % anArray.length] = anArray[i];
}
for (int i = 0; i < secondArray.length; i++){
System.out.print(secondArray[i] + " ");
}
As for how the "%" works, Codility - CyclicRotation this link should had a clear explanation.
Below function can help you
public static void rightRotateArray(int[] a, int requiredIterations) {
// right-rotate [a] by k moves
// totalActiveIterations by MOD
// => because every n(a.length) rotations ==> we receive the same array
int totalActiveIterations = requiredIterations % a.length;
for (int i = 0; i < totalActiveIterations; i++) {
// make lastElement as BKP temp
int temp = a[a.length - 1];
// make other elements => each one equal previous one [starting by lastElement]
for (int j = (a.length - 1); j >= 1; j--) {
a[j] = a[j - 1];
}
// make 1stElement equal to (BKP as temp = lastElement)
a[0] = temp;
}
}
Something like this should work
private void shiftArrayRight() {
int endElementvalue = element[element - 1];
int[] startElements = Arrays.copyOfRange(element, 0 , element.length - 1);
element[0] = endElementvalue;
for(int i = 0, x = 1; i < startElements.length; i++, x++) {
element[x] = startElements[i];
}
System.out.println(Arrays.toString(element);
}
The other answers are merely code dumps, with zero explanations. Here's an algorithm I came up with:
We rotate the array in place. Observe that the target position of every element is given by (index + k) modulo size. For range 0 to k - 1, we recursively swap each element with the one in its target position as long as the target position is greater than the current position. This is because since we are incrementally progressing from lower to higher indices, a smaller target index indicates that the corresponding element had already been swapped.
Example:
Rotate [1, 2, 3, 4, 5, 6] by 3
Index to target index:
0 to 3
1 to 4
2 to 5
3 to 0
4 to 1
5 to 2
swap(0, 3) => [4, 2, 3, 1, 5, 6]
swap(0, 0) => return
swap(1, 4) => [4, 5, 3, 1, 2, 6]
swap(1, 1) => return
swap(2, 5) => [4, 2, 6, 1, 2, 3]
swap(2, 2) => return
Done!
Another example:
Rotate [2, 3, 4, 1] by 1
Index to target index:
0 to 1
1 to 2
2 to 3
3 to 0
swap(0, 1) => [3, 2, 4, 1]
swap(0, 2) => [4, 2, 3, 1]
swap(0, 3) => [1, 2, 3, 4]
swap(3, 0) => return
Done!
Code:
static void rotateRight(int[] xs, int k) {
swap(0, 0, xs, k);
}
private static void swap(int original, int current, int[] xs, int k) {
int target = (original + k) % xs.length;
if (target > current) {
int tmp = xs[current];
xs[current] = xs[target];
xs[target] = tmp;
swap(target, current, xs, k);
}
}
public static List<int> rotateLeft(int d, List<int> arr)
{
int listSize = arr.Count();
int[] newArr = new int[listSize];
for(int oldIndex=0; oldIndex< listSize; oldIndex++)
{
int newIndex = (oldIndex + (listSize - d))% listSize;
newArr[newIndex] = arr[oldIndex];
}
List<int> newList = new List<int>(newArr);
return newList;
}
the easiest way is to use c++ 11 and above, in Codility test for Cyclicrotation.
imagine doing it in earlier versions, Duh!
#include <algorithm>
#include <iterator>
vector<int> solution(vector<int> &A, int K) {
if (A.size() == 0) {
return A;
}
for (int i=0;i<K;i++) {
//Create auciliary array
std::vector<int> aux(A.size());
//copy array to be rotated there by means of C++11
std::copy(std::begin(A), std::end(A), std::begin(aux));
//insert last element from aux to begining of the array
A.insert(A.begin(), aux.end()-1, aux.end());
//remove last element which is already become first
A.pop_back();
}
return A;
}
Just change the code like this
public void makeRight(int x) {
int[] anArray = {0, 1, 2, 3, 4, 5};
int counter = 0;
while(counter< x){
int temp = anArray[anArray.length - 1];
for (int i = anArray.length - 1; i > 0; i--) {
anArray[i] = anArray[i - 1];
}
anArray[0] = temp;
counter++;
}
for (int i = 0; i < anArray.length; i++)
System.out.print(anArray[i] + " ");
}

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] + " ");
}
}

Depth first search bug?

So I have a matrix of N×M. At a given position I have a value which represents a color. If there is nothing at that point the value is -1. What I need to do is after I add a new point, to check all his neighbours with the same color value and if there are more than 2, set them all to -1.
If what I said doesn't make sense what I'm trying to do is an algorithm which I use to destroy all the same color bubbles from my screen, where the bubbles are memorized in a matrix where -1 means no bubble and {0,1,2,...} represent that there is a bubble with a specific color.
Also, if you have any suggestions I'd be grateful. Thanks.
This is what I tried and failed:
public class Testing {
static private int[][] gameMatrix=
{{3, 3, 4, 1, 1, 2, 2, 2, 0, 0},
{1, 4, 1, 4, 2, 2, 1, 3, 0, 0},
{2, 2, 4, 4, 3, 1, 2, 4, 0, 0},
{0, 4, 2, 3, 4, 1, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
};
static int Rows=6;
static int Cols=10;
static int count;
static boolean[][] visited=new boolean[15][15];
static int NOCOLOR = -1;
static int color = 1;
public static void dfs(int r, int c, int color, boolean set)
{
for(int dr = -1; dr <= 1; dr++)
for(int dc = -1; dc <= 1; dc++)
if(!(dr == 0 && dc == 0) && ok(r+dr, c+dc))
{
int nr = r+dr;
int nc = c+dc;
// if it is the same color and we haven't visited this location before
if(gameMatrix[nr][nc] == color && !visited[nr][nc])
{
visited[nr][nc] = true;
count++;
dfs(nr, nc, color, set);
if(set)
{
gameMatrix[nr][nc] = NOCOLOR;
}
}
}
}
static boolean ok(int r, int c)
{
return r >= 0 && r < Rows && c >= 0 && c < Cols;
}
static void showMatrix(){
for(int i = 0; i < gameMatrix.length; i++) {
System.out.print("[");
for(int j = 0; j < gameMatrix[0].length; j++) {
System.out.print(" " + gameMatrix[i][j]);
}
System.out.println(" ]");
}
System.out.println();
}
static void putValue(int value,int row,int col){
gameMatrix[row][col]=value;
}
public static void main(String[] args){
System.out.println("Initial Matrix:");
putValue(1, 4, 1);
putValue(1, 5, 1);
putValue(1, 4, 2);
showMatrix();
for(int n = 0; n < Rows; n++)
for(int m = 0; m < Cols; m++)
visited[n][m] = false;
//reset count
count = 0;
dfs(5,1,color,false);
//if there are more than 2 set the color to NOCOLOR
for(int n = 0; n < Rows; n++)
for(int m = 0; m < Cols; m++)
visited[n][m] = false;
if(count > 2)
{
dfs(5,1,color,true);
}
System.out.println("Matrix after dfs:");
showMatrix();
}
}
One issue you are encountering is that you do not check the upper row and leftest col:
static boolean ok(int r, int c)
{
return r > 0 && r < Rows && c > 0 && c < Cols;
}
you should check for r >= 0, c>= 0
Second issue is you are using dfs() twice, but the visited field is static - it is all set to true before the second run of dfs() you need to initialize it back to false in all fields before the second run, or the algorithm will terminate instantly without doing anything [since all the nodes are already in visited - and the algorithm will decide not to re-explore these nodes.].
Your code counts diagonal cells as neighbours too. If you want only left/right/top/bottom cells than you can check
if(!(dr == 0 && dc == 0) && ok(r+dr, c+dc) && dr * dc == 0)
You also need to count first cell. You don't count cell you start from.
I think you are after a flood-fill algorithm (perhaps with the slightly odd constraint that there must be at least two neighbours of the same colour)? I'm not sure why depth-first-search is appropriate here.

Categories

Resources