Searching a 2D Array - java

I have instantiated a 2D array of an editable number of rows and a set number of three columns.
It is randomly filled with 0's and 1's using the Random .nextInt(2) method.
After the array is filled, I want to be able to search the array and return the first occurrence of a 0.
How can I do this?
For example, if i had an array that looked something like this:
1 1 0
0 1 0
1 1 1
The first occurence would be at (0,3). I want to search the array horizontally and when it reaches the third column (the end), it will go to the next row.
Note: I originally tested the following section of code with a 2D array that was completely filled with 0's and when I manually inserted 1's in the array and then tried to search for the first occurence of a 0 it worked. However, the code doesn't work when the array is randomly filled..
public String findNextAvailable()
{
for (int i=0; i<seatlist.length; i++)
{
for (int j=0; j<seatlist[i].length; j++)
{
int k=0;
if (seatlist[0][0]==0)
{
nextavailable= seatchart[0][0];
break;
}
else
if(seatlist[k][j]==0)
{
nextavailable= seatchart[k][j];
break;
}
else
{ k++;
if(seatlist[k][j]==0)
{
nextavailable= seatchart[k][j];
break;
}
}
}
}
return nextavailable;
}
Thanks in advance!

for (int i = 0; i < seats.length; i++) {
for (int j = 0; j < seats[i].length; j++) {
if (seats[i][j] == 0) {
return "Next available seat at position: [" + i + "][" + j + "]";
}
}
}
return "No seat available";
Although you might want to create a seat object instead that is easier to work with:
public class Seat {
private int row;
private int column;
public Seat(int row, int column){
this.row = row;
this.column = column;
}
public int getRow() {
return row;
}
public int getColumn() {
return column;
}
}
and replace the returning of a string with:
return new Seat(i,j);

well when you break in the inner loop, you still execute again the outer loop and you wind up replacing what you think is your final result by the next run of the outer loop. rather than use break, just return right there.

You need to return the positions of the first encountered 0, so why are you breaking out of the if statement, the outer loop will still run!
Simply create an integer array:
int[] pos=new array[2];
Change the return type:
public int[] findNextAvailable(){
In each of the if statements change the contents so that it reads:
pos[0]=i;
pos[1]=j;
return pos;
The end result will look something like this:
public int[] findNextAvailable()
{
int[] pos=new array[2];
for (int i=0; i<seatlist.length; i++)
{
for (int j=0; j<seatlist[i].length; j++)
{
if (seatlist[i][j]==0)
{
pos[0]=i;
pos[1]=j;
return pos;
}
}
}
//none found so return minus one.
pos[0]=-1;
pos[1]=-1;
return pos;
}

there are many different types of searches, some faster and some easier to do. Here's a program i made that has methods for all types of them. you will have to modify them a bit so it will search a 2d array but it shouldn't be too hard.
'
package linear_search;
import java.util.Arrays;
import java.util.Scanner;
public class Linear_search {
int[] array = {10,12,42,7,22,1,3,4,5,9};
int ans;
int num;
int min;
int max;
void start(){
arraySort(array);
dump(array);
Scanner scan = new Scanner(System.in);
System.out.println("Enter a value to search:");
num = scan.nextInt();
ans = recursiveBinarySearch(array, 0, array.length-1);
if(ans == -1){
System.out.println("Your value was not found");
} else {
System.out.println("Your value was found at position " + ans);
}
}
void dump(int[] array){
for(int i = 0; i < array.length ; i++){
System.out.print(array[i] + " ");
}
System.out.println();
}
int linearsearch(int[] array){
for(int i = 0; i < array.length; i++){
if(array[i] == num){
return i;
}
}
return -1;
}
int binarysearch(int[] array){
min = 0;
max = array.length -1;
int mid = (min + max) / 2;
while(array[mid] != num){
if(num > array[mid]){
min = mid+1;
mid = (min + max) / 2;
}
if(num < array[mid]){
max = mid-1;
mid = (min + mid) / 2;
}
if(min == max && array[mid] != num){
return -1;
}
}
return mid;
}
int recursiveBinarySearch(int[] array, int min, int max){
int mid = (min + max) / 2;
if(array[mid] == num){
return mid;
}
if(min == max && array[mid] != num){
return -1;
}
if(num > array[mid]){
return recursiveBinarySearch(array, mid+1, max);
}
if(num < array[mid]){
return recursiveBinarySearch(array, min, mid-1);
}
return mid;
}
void arraySort(int[] a){
Arrays.sort(array);
}
public static void main(String[] args) {
Linear_search main = new Linear_search();
main.start();
}
}
'
you will just have to remove the scanner and hard code in "0" for the default value you should search for.

Related

Can you help me identify the error in this code? I dont seem to understand why it isn't working?

https://www.hackerrank.com/challenges/new-year-chaos/problem?h_l=interview&playlist_slugs%5B%5D=interview-preparation-kit&playlist_slugs%5B%5D=arrays
The link to the question I'm having trouble in...
My logic was to start a loop from the end of the array and move forwards, checking which elements are in position, and swapping to get the elements in their right position, I'm attaching my code below. I swap one by one because that's how they showed it in the sample test case.
static void minimumBribes(int[] q) {
int moves = 0;
boolean tc = false;
for(int i = q.length-1; i >= 0; i--){
if(q[i] != i+1 && q[i] >= (i+1)){
int diff = q[i] - (i+1);
if(diff > 2){
System.out.println("Too chaotic");
tc = true;
}else{
moves = moves + diff;
for(int j = 1; j <= diff; j++){
arrSwap(q, i-1+j, i+j);
}
i--;
}
}else{
continue;
}
}
if(tc == false){
System.out.println(moves);
}
}
public static void arrSwap (int[] arr, int i, int j) {
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
Input:
1 2 5 3 4 7 8 6
Output:
3
Expected Output:
4
You can use Bobble sortting solve this problem.Here is my code:
static void minimumBribes(int[] q) {
int []res=new int[q.length];
boolean change=true;
for(int i=0;i<q.length;i++)
res[i]=0;
while(change){
change=false;
for(int i=0,j=i+1;j<q.length;i++,j++){
if(q[i]>q[j]){
res[q[i]-1]++;
arrSwap(q,i,j);
change=true;
}
}
}
int n=0;
for(int i=0;i<q.length;i++){
if(res[i]>2){
System.out.println("Too chaotic");
return;
}
else
n+=res[i];
}
System.out.println(n);
}
public static void arrSwap (int[] arr, int i, int j) {
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
My code may be not the best solution.

Function takes a martix (2d array) and prints the max number of the even numbers in each line

I am defining a function to accept a matrix (2d array), for example x[][]; and the function should print the biggest even number in each line
public static void biggestEvenNumOfEachLine(int x[][]){
int even,t=0,max;
int arr[] = new int [x.length];
for(int i = 0; i < x.length;i++){
for(int j = 0; j < x[i].length;j++,t++){
if(x[i][j] % 2 == 0){
even = x[i][j];
arr[j] = even;
}
}
}
}
What am I missing?
I would start by finding the biggest even number in a single line array. Start with the smallest possible value, and then iterate the array. Test for even, and then set the max (and then return it). Something like,
private static int biggestEvenNum(int[] x) {
int max = Integer.MIN_VALUE;
for (int i = 0; i < x.length; i++) {
if (x[i] % 2 == 0) {
max = Math.max(max, x[i]);
}
}
return max;
}
But, in Java 8+, I would prefer to filter for even values and get the max like
private static int biggestEvenNum(int[] x) {
return IntStream.of(x).filter(v -> v % 2 == 0).max().getAsInt();
}
Then your method is as simple as iterating the line(s) in your matrix, printing the result. Like,
public static void biggestEvenNumOfEachLine(int[][] x) {
for (int[] line : x) {
System.out.println(biggestEvenNum(line));
}
}
public static void biggestEvenNumOfEachLine(int x[][])
{
int arr[] = new int [x.length];
for(int i = 0; i < x.length;i++)
for(int j = 0; j < x[i].length;j++)
if(x[i][j] % 2 == 0 && x[i][j] > arr[i]){
arr[i] = x[i][j];
System.out.println(arr[i]);
}
}
This will work but if there is no even number at particular line then corresponding number to that line will be zero.

Subset sum negative values

I was wondering how to work with negative values and a negative target, right now my program gives index out of bounds errors whenever negative values are given to these variables. I need my hasSum function work with negative values for this project, I can't just assume positive.
import java.util.Stack;
import java.util.Scanner;
public class subsetSum {
static Scanner input = new Scanner(System.in);
static {
System.out.print("Enter the target (T)" + "\n");
}
/** Set a value for target sum */
static int TARGET_SUM = input.nextInt(); //this is the target
/** Store the sum of current elements stored in stack */
static int sumInStack = 0;
Stack<Integer> stack = new Stack<Integer>();
public static void main(String[] args) {
//the size is S
System.out.println("\n" + "Enter the size of the set (S)");
int values = input.nextInt(); //size = "values"
//value of each size entry
System.out.println("\n" + "Enter the value of each entry for S");
int [] numbers = new int[values];
for(int i = 0; i < values; i++) //for reading array
{
numbers[i] = input.nextInt();
}
if(hasSum(numbers, TARGET_SUM)){
System.out.println("\n" + "Can: ");
subsetSum get = new subsetSum(); // encapsulation
get.populateSubset(numbers, 0, numbers.length);
}else{
System.out.println("\n" + "Cannot");
}
}
//method based on dynamic programming O(sum*length)
public static boolean hasSum(int [] array, int sum)
{
int i;
int len = array.length;
boolean[][] table = new boolean[sum + 1][len + 1]; //this has to be changed for negative
//If sum is zero; empty subset always has a sum 0; hence true
for(i = 0; i <= len; i++){
table[0][i] = true;
}
//If set is empty; no way to find the subset with non zero sum; hence false
for(i = 1; i <= sum; i++){
table[i][0] = false;
}
//calculate the table entries in terms of previous values
for(i = 1; i <= sum; i++)
{
for(int j = 1; j <= len; j++)
{
table[i][j] = table[i][j - 1];
if(!table[i][j] && i >= array[j - 1]){
table[i][j] = table[i - array[j - 1]][j - 1];
}
}
}
return table[sum][len]; //this has to be changed for negative
}
public void populateSubset(int[] data, int fromIndex, int endIndex) {
/*
* Check if sum of elements stored in Stack is equal to the expected
* target sum.
*
* If so, call print method to print the candidate satisfied result.
*/
if (sumInStack >= TARGET_SUM) {
if (sumInStack == TARGET_SUM) {
print(stack);
}
// there is no need to continue when we have an answer
// because nothing we add from here on in will make it
// add to anything less than what we have...
return;
}
for (int currentIndex = fromIndex; currentIndex < endIndex; currentIndex++) {
if (sumInStack + data[currentIndex] <= TARGET_SUM) {
stack.push(data[currentIndex]);
sumInStack += data[currentIndex];
/*
* Make the currentIndex +1, and then use recursion to proceed
* further.
*/
populateSubset(data, currentIndex + 1, endIndex);
sumInStack -= (Integer) stack.pop();
}
}
}
/**
* Print satisfied result. i.e. 5 = 1, 4
*/
private void print(Stack<Integer> stack) {
StringBuilder sb = new StringBuilder();
for (Integer i : stack) {
sb.append(i).append(",");
}
// .deleteCharAt(sb.length() - 1)
System.out.println(sb.deleteCharAt(sb.length() - 1).toString());
}
}
Are you trying to find a sum of subset or a subarray?
If a subset, then a simple recursion could do the trick, e.g.:
public static boolean hasSum(int [] array, int sum)
{
return hasSum(array, 0, 0, sum);
}
private static boolean hasSum(int[] array, int index, int currentSum, int targetSum) {
if (currentSum == targetSum)
return true;
if (index == array.length)
return false;
return hasSum(array, index + 1, currentSum + array[index], targetSum) || // this recursion branch includes current element
hasSum(array, index + 1, currentSum, targetSum); // this doesn't
}
If you're trying to find a subarray, I'd use prefix sums, e.g.:
public static boolean hasSum(int [] array, int sum)
{
int[] prefixSums = new int[array.length];
for (int i = 0; i < prefixSums.length; i++) {
prefixSums[i] = (i == 0) ? array[i] : array[i] + prefixSums[i - 1];
}
for (int to = 0; to < prefixSums.length; to++) {
if (prefixSums[to] == sum)
return true; // interval [0 .. to]
for (int from = 0; from < to; from++) {
if (prefixSums[to] - prefixSums[from] == sum)
return true; // interval (from .. to]
}
}
return false;
}
BTW I think reading the input values from Scanner inside the static initializer is a bad idea, why don't you move them to main()?

How use other written methods with present method

I wrote a program for this problem:
“Write a program that, given an array array[] of n numbers and another number x, determines whether or not there exist two elements in array whose sum is exactly x.”
Which is this:
boolean hasArrayTwoCandidates (int array[], int sum) {
int length = array.length;
quickSort(array, 0, length-1);
int first, last;
first = 0;
last = length-1;
while(first < last){
if( array[first] + array[last] == sum )
return true;
else if( array[first] + array[last] < sum )
first++;
else // array[i] + array[j] > sum
last--;
}
return false;
}
At first place, I don't know where should I put or add "quick sort" codes. I have this problem with other programs, as well; when I want to add written methods to the present one.
Should I create a "new class" under this "project" and put "quicksort" codes there?
Should I put them in this class? but how can I use it?
At second place, I don't know what should I write in my "main method"?
this is my quicksort codes:
public void sort(int[] values) {
if (values == null || values.length == 0){
return;
}
this.array = values;
length = values.length;
quickSort(this.array, 0, length - 1);
}
private void quickSort(int[] array, int low, int high) {
int i = low, j = high;
int pivot = array[low + (high-low)/2];
while (i <= j) {
while (array[i] < pivot) {
i++;
}
while (array[j] > pivot) {
j--;
}
if (i <= j) {
exchange(i, j);
i++;
j--;
}
}
if (low < j)
quickSort(array, low, j);
if (i < high)
quickSort(array, i, high);
}
private void exchange(int i, int j) {
int temp = array[i];
array[i] = array[j];
array[j] = temp;
}
actually, I dont know what should I write in my "main method" to run this program?
For you Question you can do simply this kind of coding in main method:
public static void main(String[]args) {
int x = 20;
int[] arr = {2,5,4,10,12,5};
System.out.println(hasArrayTwoCandidates(arr,x));
}
make the methods static
static boolean hasArrayTwoCandidates (int array[], int sum)
But there are porblems in your coding:
private void exchange(int i, int j) {
int temp = array[i];
array[i] = array[j];
array[j] = temp;
}
Here the array is not defined. you'll get an error. you have to pass the array too to the method make it as.
private void exchange(int i, int j,int[] array)
But since you are not necessary to do sorting. I recommend this.
static boolean hasArrayTwoCandidates (int array[], int sum) {
boolean flag = false;
for(int i=0;i<array.length-1;i++){
for(int j=i+1;j<array.length ;j++){
if(array[i]+array[j] == sum)
flag = true;
}
}
return flag;
}
this will get one element and check while adding other elements that it is true
Then the main method come same way.
you can put all those method in same class, make hasArrayTwoCandidates() static (Note that main method is static and a static method can have access only to static methods)
public static boolean hasArrayTwoCandidates (int array[], int sum) {
....
}
and in your main method you can test it like this :
public static void main(String[] args){
int[] arr = {2,5,12,5,2,7,15};
System.out.print(hasArrayTwoCandidates(arr, 27));
}
Answering your questions: you can write methods and call them within the same class, just write them with the static modifier:
private static <return_type> <methodName> (<type> param1, <type> param2) {
// Your code here
}
For a program like this, I don't get why you are thinking about sorting the array before checking the sum of 2 numbers within it, when you could do all at once. Check out this code, this may shine a light on you. It is straight-forward and only to see if it clarifies your logic.
import java.util.Random;
public class VerifySum {
public static void main(String[] args) {
Random rand = new Random();
int[] array = new int[10];
// Produce a random number from 10 to 20
int randomSum = rand.nextInt(11) + 10;
// Fill out the array with random integers from 0 to 10
for (int i = 0; i < array.length; i++) {
array[i] = rand.nextInt(11);
}
// Check all array indexes against each other
for (int i = 0; i < array.length - 1; i++) {
for (int j = i + 1; j < array.length; j++) {
if (array[i] + array[j] == randomSum) {
System.out.println(array[i] + " + " + array[j] + " = " + randomSum);
}
}
}
// Print "x"
System.out.println("randomSum = " + randomSum);
// Print array for verification of the functionality
for (int i = 0; i < array.length; i++) {
System.out.println("array [" + i + "] = " + array[i]);
}
}
}
Sometimes making it simpler is more efficient. ;-)

Error in Finding the nth largest number in the unsorted array (containing duplicates) using median of medians algo O(n)

If an array contains 1,7,7,3,6 and if user asks what 2nd largest element is the output should be 7(not 6) since duplicate values are treated as distinct.
This is my code.
I am using Deterministic search to find the suitable pivot .
Its complexity is O(n).
I am stuck at the error generated by my code .
Please do help me.
import java.util.Random;
import java.util.Scanner;
public class deven {
public static void main(String args[]){
Scanner in=new Scanner(System.in);
int len=in.nextInt();
int n=in.nextInt();
int array[]=new int[len];
for (int i = 0; i < len; i++) {
array[i]=in.nextInt();
}
System.out.println(select(array,len,n));
}
static int below[];
static int above[];
static int pivot;
static int i;
static int j;
static int x;
static int y;
static int index;
static Random rand=new Random();
static int select(int array[],int len,int n){
if(len==1)
return array[0];
pivot=pivot(array, len);
below=new int[len];
above=new int[len];
//System.out.println("Block");
x=0;
y=0;
int temp=0;
for(i=0;i<len;i++){
if(array[i]>pivot){
below[x++]=array[i];
}
else if(array[i]<pivot){
above[y++]=array[i];
}
else {
if(temp!=0){
below[x++]=array[i];
}
temp=1;
}
}
i = x;
j = len - y;
if(n<i) return select(below,x,n);
else if(n>=j) return(select(above,y,n-j));
else return(pivot);
}
static int pivot(int array[],int len){
if(len==1){
return array[0];
}
int numOfGroups=len/5;
if(len%5!=0){
numOfGroups++;
}
int setOfMedians[]=new int[numOfGroups];
for (int i = 0 ; i < numOfGroups ; i++)
{
int[] subset;
if(array.length % 5 > 0)
{
if (i == numOfGroups - 1)
{
subset = new int[array.length % 5];
}
else
{
subset = new int[5];
}
}
else
{
subset = new int[5];
}
for (int j = 0; j < subset.length ; j++)
{
subset[j] = array[5*i+j];
}
setOfMedians[i] = median(subset);
}
int goodpivot=select(setOfMedians, numOfGroups,numOfGroups/2 );
return goodpivot;
}
static int median(int[] array)
{
if (array.length == 1)
{
return array[0];
}
int smallerCount = 0;
for (int i = 0 ; i < array.length ; i++)
{
for (int j = 0 ; j < array.length ; j++)
{
if (array[i] < array[j])
{
smallerCount++;
}
}
if (smallerCount == (array.length - 1)/2)
{
return array[i];
}
smallerCount = 0;
}
return -1;
}
}
Input
6
3
1 2 3 1 2 3
Output
Exception in thread "main" java.lang.StackOverflowError
at deven.pivot(deven.java:99)
at deven.select(deven.java:34)
at deven.pivot(deven.java:102)
at deven.select(deven.java:34)
at deven.select(deven.java:59)
at deven.select(deven.java:59)
at deven.select(deven.java:59)
If you maintained an equalsCount in addition to your smallerCount, you should be able to detect whether your candidate value is the median when it is also a duplicate.
(Explanation)
You appear to be deliberately returning -1 as an invalid value when your median method fails unexpectedly. It would be more proper to throw an exception of some sort, but what you really want is for it to never reach that point.
Your algorithm fails when the median is a duplicate. In the set { 1, 2, 2, 2, 3 }, for example, 2 is the obvious median, but there's never a point where there are exactly 2 values "smaller than" any of the values being verified.
If you count both smaller and equal values, then you can know your candidate to be a median if either your current test passes, or if the smaller count is less than the midpoint AND the smaller + equal count is greater than the midpoint.
The problem is your median method. It should not return -1. In the last line of the median method, instead of
return -1;
change it to
return array[rand.nextInt(array.length)];
Please note that this fix is just an attempt to fix the error you have. It's not a good fix in the sense that median method does not return the median. I think the application should be refactored. The idea of the fix is actually in the pivot method. A good pivot is the median. But if you cannot find the median efficiently, then a pivot can be a random choice among the array.
Update:
Let's fix the median method:
static int median(int[] array) {
if (array.length == 0) {
throw new IllegalArgumentException("array cannot be empty.");
}
int mid = array.length / 2;
for (int candidate : array) {
int lower = 0;
int higher = 0;
for (int value : array) {
if (value < candidate) {
lower++;
}
else if (value > candidate) {
higher++;
}
}
if (lower <= mid && higher <= mid) {
return candidate;
}
}
throw new IllegalStateException();
}

Categories