Related
Find patterns in a given matrix.
I have a matrix with values '.' and '#'
Now I want to find count with the given pattern in the matrix :
a)
##
b)
#
#
For the above pattern, the cells if exist surrounding them should be '.'
I am able to create successful logic for it:
static int getMatches(String[] B, int m, int n) {
int count = 0;
boolean[][] flag = new boolean[m][n];
for (int i = 0; i < m; i++) {
String S = B[i];
for (int j = 0; j < n; j++) {
char c = S.charAt(j);
boolean valid = true;
if (c == '#' && flag[i][j] == false) {
if (j + 1 < n && S.charAt(j + 1) == '#' && flag[i][j + 1] == false) {
int[][] adj = { { 0, -1 }, { 0, 2 }, { -1, 0 }, { -1, 1 }, { 1, 0 }, { 1, 1 } };
valid = isValid(adj, i, j, m, n, B);
} else {
valid = false;
}
} else {
valid = false;
}
if (c == '#' && !valid && flag[i][j] == false) {
if (i + 1 < m && S.charAt(i + 1) == '#' && flag[i + 1][i] == false) {
int[][] adj = { { 0, -1 }, { 1, -1 }, { 1, 1 }, { 0, 1 }, { -1, 0 }, { 2, 0 } };
valid = isValid(adj, i, j, m, n, B);
} else {
valid = false;
}
}
flag[i][j] = true;
if (valid) {
count++;
}
}
}
return count;
}
static boolean isValid(int[][] adj, int i, int j, int m, int n, String[] B) {
for (int a = 0; a < adj.length; a++) {
int i1 = i + adj[a][0];
int j1 = j + adj[a][1];
if (i1 >= 0 && i1 < m) {
if (j1 >= 0 && j1 < n) {
char d = B[i1].charAt(j1);
if (d == '#') {
return false;
}
}
}
}
return true;
}
Now I want to change the pattern to 3 cells like this:
a)
###
b)
#
#
#
c)
##
#
d)
##
#
e)
#
##
f)
#
##
How to build logic for this? Is their a way to extend my above code or is there a better approach to solve this problem.
As far as I understand, the problem can be simplified to finding the adjacent # fields, and their area must match a certain number.
So I have created the following code:
public static int getMatches(String[] matrix, int m, int n, int patternArea) {
int count = 0;
for (int i = 0; i < m; i++) {
String row = matrix[i];
for (int j = 0; j < n; j++) {
char item = row.charAt(j);
if (item == '#' && countArea(matrix, i, j) + 1 == patternArea) {
count++;
}
}
}
return count;
}
private static int countArea( String[] matrix, final int i, final int j ) {
int area = 0;
setVisited(matrix, i,j);
if (matrix[Math.max(i-1, 0)].charAt(j) == '#') {
area += countArea(matrix, i-1, j) + 1;
}
if (matrix[Math.min(i+1, matrix.length-1)].charAt(j) == '#') {
area += countArea(matrix, i+1, j) + 1;
}
if (matrix[i].charAt(Math.max(j-1, 0)) == '#') {
area += countArea(matrix, i, j-1) + 1;
}
if (matrix[i].charAt(Math.min(j+1, matrix[0].length()-1)) == '#') {
area += countArea(matrix, i, j+1) + 1;
}
return area;
}
private static void setVisited( final String[] matrix, final int i, final int j ) {
char[] rowChars = matrix[i].toCharArray();
rowChars[j] = '0';
matrix[i] = String.valueOf(rowChars);
}
Explanation:
Find at least 1 # field
From that position, recursively find any adjacent # fields - countArea method
Always mark already visited fields - I chose 0, but any other char will do other than . and #
Finally, if the area is matching a given number (patternArea), increase count variable
This is working only, if you include all of the patterns for a certain number. Given your example, you did just that. In case you really want to do exact pattern matching, then this approach will not be useful for your case.
Shared solution should work with any matrix of any symbols and number of rows/columns
Let's assume next parameters that we'll have as our input:
Matrix is represented as two-dimensional array - matrix[r][c], where r - number of rows in matrix, c - number of columns in matrix
Matrix has all its cells filled with some symbols
Pattern is represented as two-dimensional array - arr[k][m], where k - number of rows in pattern, m - number of columns in pattern
Algorithm will iterate each column of each row in matrix
Pattern can potentially be present in cell[x][y] only if next conditions are met:
x + k <= r (there are enough of matrix rows below this one (including current row) to include number of pattern rows)
y + m <= c (there are enough of matrix columns right of this one (including current column) to include number of pattern columns)
Comparison of pattern to current matrix cells says that they are equal. Comparison in done based on next conditions:
if pattern character is null - continue comparison
if pattern character is equal to matrix character - continue comparison
if pattern character is not equal to matrix character - end comparison, pattern is not located in this cell
if all pattern symbols checked - pattern is found in given matrix cell
Result of comparison in represented in 0-based index pairs
Let's get to the code.
We will have next classes:
Pattern Rule - represents pattern to be found. please specify nulls manually to make actually 2-dimensional array of equal row/col count
private static final class PatternRule {
private final Character[][] pattern;
private final int rowCount;
private final int colCount;
private PatternRule(Character[][] pattern) {
this.pattern = pattern;
this.rowCount = pattern.length;
this.colCount = pattern[0].length;
}
public int getRowCount() {
return rowCount;
}
public int getColCount() {
return colCount;
}
public Character getCharacterAt(int row, int column) {
return pattern[row][column];
}
}
Found Pattern Location - class to represent found cells for pattern locations
private static final class FoundPatternLocation {
private final int rowIndex;
private final int colIndex;
private FoundPatternLocation(int rowIndex, int colIndex) {
this.rowIndex = rowIndex;
this.colIndex = colIndex;
}
#Override
public String toString() {
return "[" + rowIndex + "][" + colIndex + "]";
}
}
Matrix - class that creates matrix and performs search of pattern locations
private static final class Matrix {
private final Character[][] matrix;
private final int rowCount;
private final int colCount;
private Matrix(int rowCount, int colCount, Character[][] matrix) {
this.rowCount = rowCount;
this.colCount = colCount;
this.matrix = matrix;
}
public static Matrix createMatrix(int rowCount, int colCount, char[] matrixSymbols) {
Character[][] newMatrix = new Character[colCount][rowCount];
Random rand = new Random();
for (int rowIndex = 0; rowIndex < rowCount; rowIndex++) {
for (int colIndex = 0; colIndex < colCount; colIndex++) {
// select random char from allowed symbols
newMatrix[rowIndex][colIndex] = matrixSymbols[rand.nextInt(matrixSymbols.length)];
}
}
return new Matrix(rowCount, colCount, newMatrix);
}
public void printMatrix() {
System.out.println("---- Matrix -----");
for (int rowIndex = 0; rowIndex < rowCount; rowIndex++) {
List<String> rowValues = new ArrayList<>();
for (int colIndex = 0; colIndex < colCount; colIndex++) {
rowValues.add(String.valueOf(matrix[rowIndex][colIndex]));
}
String printableRowString = String.join(" ", rowValues);
System.out.println(printableRowString);
}
System.out.println("-----------------");
}
public List<FoundPatternLocation> findPatternLocations(PatternRule patternRule) {
List<FoundPatternLocation> actualPatternLocation = new ArrayList<>();
for (int rowNum = 0; rowNum < this.rowCount; rowNum++) {
for (int colNum = 0; colNum < this.colCount; colNum++) {
if (isPatternFittingToCurrentCell(rowNum, colNum, patternRule)) { // can pattern be located in this cell?
if (isPatternLocatedInCell(rowNum, colNum, patternRule)) { // is pattern actually located in this cell?
actualPatternLocation.add(new FoundPatternLocation(rowNum, colNum));
}
}
}
}
return actualPatternLocation;
}
private boolean isPatternFittingToCurrentCell(int matrixRowIndex, int matrixColIndex, PatternRule patternRule) {
int patternRowsCount = patternRule.getRowCount();
int patternColumnsCount = patternRule.getColCount();
int availableMatrixRowsForPattern = rowCount - matrixRowIndex;
int availableMatrixColsForPattern = colCount - matrixColIndex;
return patternRowsCount <= availableMatrixRowsForPattern && patternColumnsCount <= availableMatrixColsForPattern;
}
private boolean isPatternLocatedInCell(int rowNum, int colNum, PatternRule patternRule) {
int patternRowsCount = patternRule.getRowCount();
int patternColumnsCount = patternRule.getColCount();
for (int currentPatternRowIndex = 0; currentPatternRowIndex < patternRowsCount; currentPatternRowIndex++) {
for (int currentPatternColIndex = 0; currentPatternColIndex < patternColumnsCount; currentPatternColIndex++) {
int currentMatrixRowIndex = currentPatternRowIndex + rowNum;
int currentMatrixColIndex = currentPatternColIndex + colNum;
Character currentMatrixCharacter = matrix[currentMatrixRowIndex][currentMatrixColIndex];
Character currentPatternCharacter = patternRule.getCharacterAt(currentPatternRowIndex, currentPatternColIndex);
if (currentPatternCharacter == null) {
continue;
}
if (Objects.equals(currentMatrixCharacter, currentPatternCharacter)) {
continue;
}
return false;
}
}
return true;
}
}
Class to perform execution
public static void main(String[] args) {
int rowCount = 5;
int colCount = 5;
char[] matrixSymbols = new char[] {'✓', 'X'};
Matrix matrix = Matrix.createMatrix(rowCount, colCount, matrixSymbols);
matrix.printMatrix();
PatternRule patternRuleA = createPatternRuleA();
PatternRule patternRuleB = createPatternRuleB();
PatternRule patternRuleC = createPatternRuleC();
List<FoundPatternLocation> patternLocationsA = matrix.findPatternLocations(patternRuleA);
printPatternLocations(patternLocationsA, "Pattern A");
List<FoundPatternLocation> patternLocationsB = matrix.findPatternLocations(patternRuleB);
printPatternLocations(patternLocationsB, "Pattern B");
List<FoundPatternLocation> patternLocationsC = matrix.findPatternLocations(patternRuleC);
printPatternLocations(patternLocationsC, "Pattern C");
}
private static void printPatternLocations(List<FoundPatternLocation> patternLocations, String patternName) {
System.out.println("---- " + patternName + " ----");
String string = patternLocations.stream().map(FoundPatternLocation::toString).collect(Collectors.joining("; "));
System.out.println(string);
System.out.println("--------");
}
private static PatternRule createPatternRuleA() {
Character[][] chars = {
{'✓', '✓', '✓'}
};
return new PatternRule(chars);
}
private static PatternRule createPatternRuleB() {
Character[][] chars = {
{'✓'},
{'✓'},
{'✓'}
};
return new PatternRule(chars);
}
private static PatternRule createPatternRuleC() {
Character[][] chars = {
{'✓', '✓'},
{'✓', null}
};
return new PatternRule(chars);
}
Example of execution:
---- Matrix -----
✓ ✓ X ✓ X
✓ ✓ ✓ ✓ ✓
X X X X ✓
X ✓ X X ✓
X X ✓ ✓ ✓
-----------------
---- Pattern A ----
[1][0]; [1][1]; [1][2]; [4][2]
--------
---- Pattern B ----
[1][4]; [2][4]
--------
---- Pattern C ----
[0][0]
--------
Problem : You have L, a list containing some digits (0 to 9). Write a function solution(L) which finds the largest number that can be made from some or all of these digits and is divisible by 3. If it is not possible to make such a number, return 0 as the solution. L will contain anywhere from 1 to 9 digits. The same digit may appear multiple times in the list, but each element in the list may only be used once.
Test Cases :
Input:
Solution.solution({3, 1, 4, 1})
Output: 4311
Input:
Solution.solution({3, 1, 4, 1, 5, 9})
Output: 94311
My Program :
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.stream.IntStream;
public class Solution {
static ArrayList<Integer> al = new ArrayList<Integer>();
static ArrayList<Integer> largest = new ArrayList<Integer>();
static int o = 1;
static int po = 0;
static void combinations(String[] digits, String[] data, int start, int end, int index, int r)
{
if (index == r)
{
String temp = "0";
for (int j = 0; j < r; j++)
{
temp = temp + data[j];
// System.out.print(data[j]);
}
Integer d = Integer.parseInt(temp);
al.add(d);
// System.out.println(al);
}
for (int i = start; i <= end && ((end - i + 1) >= (r - index)); i++)
{
data[index] = digits[i];
combinations(digits, data, i + 1, end, index + 1, r);
}
}
static void printCombinations(String[] sequence, int N)
{
String[] data = new String[N];
for (int r = 0; r < sequence.length; r++)
combinations(sequence, data, 0, N - 1, 0, r);
}
static String[] convert(int[] x)
{
String c[] = new String[x.length];
for(int i=0; i < x.length; i++)
{
Integer k = x[i];
if(k==0)
{
o = o * 10;
continue;
}
c[i] = k.toString();
}
// System.out.println(o);
c = Arrays.stream(c).filter(s -> (s != null && s.length() > 0)).toArray(String[]::new);
po = c.length;
// System.out.println("Come"+ Arrays.asList(c));
return c;
}
public static int solution(int[] l) {
if(l.length==0)
return 0;
if(IntStream.of(l).sum()%3==0)
{
String x = "";
Arrays.sort(l);
for (int i = l.length - 1; i >= 0; i--) {
x = x + l[i];
}
return Integer.parseInt(x);
}
printCombinations(convert(l),po);
al.sort(Comparator.reverseOrder());
al.remove(al.size()-1);
al.removeIf( num -> num%3!=0);
if(al.isEmpty())
return 0;
for(int i=0; i< al.size(); i++)
{
Integer n = al.get(i);
printMaxNum(n);
}
// System.out.println(al);
// System.out.println(largest);
return largest.get(0)*o;
}
static void printMaxNum(int num)
{
// hashed array to store count of digits
int count[] = new int[10];
// Converting given number to string
String str = Integer.toString(num);
// Updating the count array
for(int i=0; i < str.length(); i++)
count[str.charAt(i)-'0']++;
// result is to store the final number
int result = 0, multiplier = 1;
// Traversing the count array
// to calculate the maximum number
for (int i = 0; i <= 9; i++)
{
while (count[i] > 0)
{
result = result + (i * multiplier);
count[i]--;
multiplier = multiplier * 10;
}
}
// return the result
largest.add(result);
}
public static void main(String[] args) {
System.out.println(solution(new int[]{9,8,2,3}));
}
}
My Code passes both given test cases and 3 other hidden test cases except one. I tried all possible input combinations but couldn't get to the exact failure. The return type by default is given as int and therefore they would not pass values which give output that does not fit in int. Any other scenario where my code fails?
I am a first year programming trying to solve this challenge that was given to us students at uni.
Question image
There's a typo at where it says (N + K) whereas in fact it's actually (M+K) columns.
My attempt for this question goes as follows
public static int[][] mergeArrays(int[][] arrayA, int[][] arrayB){
int rows = 3;
int columns = arrayA[0].length + arrayB[0].length;
int[][] mergedArray = new int[rows][columns];
int k = 0;
for (int i = 0; i < rows; i++)
{
for ( int j = 0 ; j < columns; j++)
{
try
{
mergedArray[i][j] = arrayA[i][j];
}
catch (ArrayIndexOutOfBoundsException e)
{
mergedArray[i][j] = arrayB[i][k];
k += 1;
}
}
}
return mergedArray;
}
public static void main(String [] args)
{
int [][] a1 = { {1,2,3,3,3} , {3,2,1,6,3} , {4,5,6,1,3} };
int [][] a2 = { {1,9,7,2,3} , {0,7,8,3,2} , {3,8,9,7,2} };
int[][] m = mergeArrays(a1,a2);
for (int[] x : m)
{
for (int y : x)
{
System.out.print(y + " ");
}
System.out.println();
}
}
The program doesn't work for some reason. I don't know what's wrong with my approach here. Would really appreciate if someone helps me out.
Without using any libraries, in a manual way, here is my working answer.
I didn't use any of them, since we were not allowed, when I was a student.
public class Main {
private static int[][] mergeArrays(int[][] a1, int[][] a2) {
// Count rows and cols length.
int rows = a1.length;
int cols_a1 = a1[0].length;
int cols_a2 = a2[0].length;
// Total number of cols
int cols = cols_a2 + cols_a1;
int [][] merged = new int[rows][cols];
for (int i = 0; i < rows ; ++i) {
for (int j = 0; j < cols_a1; ++j) {
merged[i][j] = a1[i][j];
}
// To not overwrite values,
// the trick is to add an offset, while assigning,
// which is the amount of elements (cols_a1) used by the previous loop.
// Basically, we are shifting the k-index by this constant,
// as to not overwrite the values assigned from the previous
// inner loop.
for (int k = 0; k < cols_a2; ++k) {
merged[i][cols_a1 + k] = a2[i][k];
}
}
// Return the merged array
return merged;
}
// I refactored your good printing code into a method, for readability.
private static void print2darray(int[][] array2d) {
for (int[] x : array2d) {
for (int y : x) {
System.out.print(y + " ");
}
System.out.println();
}
}
public static void main(String[] args) {
int [][] a1 = {{1,2,3,3,3} , {3,2,1,6,3} , {4,5,6,1,3}};
int [][] a2 = {{1,9,7,2,3} , {0,7,8,3,2} , {3,8,9,7,2}};
int [][] merged = mergeArrays(a1, a2);
print2darray(merged);
}
}
The result is the same, as expected, from your question image:
1 2 3 3 3 1 9 7 2 3
3 2 1 6 3 0 7 8 3 2
4 5 6 1 3 3 8 9 7 2
Since you're a student I think to better if we give a hint, but since the solution is already there you can check this one as well:
public static int[] merge(int[] first,int[] second) {
return ArrayUtils.addAll(first, second);
}
public static void main(String[] args) {
int [][] a1 = { {1,2,3,3,3} , {3,2,1,6,3} , {4,5,6,1,3}};
int [][] a2 = { {1,9,7,2,3} , {0,7,8,3,2} , {3,8,9,7,2}};
int [][] a3 = new int[a1.length][];
for (int i = 0; i < a1.length; i++) {
a3[i] = merge(a1[i],a2[i]);
}
for (int[] ints : a3) {
StringJoiner joiner = new StringJoiner(",","[","]");
for (int i1 : ints) {
joiner.add(i1+"");
}
System.out.println(joiner.toString());
}
}
You are not merging it properly. Your logic is that if arrayA column index is out of bounds, you are adding from arrayB's columns. But what if that is also out of bounds, as in your case. Since you are always incrementing its index k. You could simply iterate over 2 arrays separately and merge into resulting array.
public static int[][] mergeArrays(int[][] arrayA, int[][] arrayB) {
int rows = 3;
int columns = arrayA[0].length + arrayB[0].length;
int[][] mergedArray = new int[rows][columns];
int k = 0;
for (int i = 0; i < rows; i++) {
for (int j = 0; j < arrayA[0].length; j++) {
mergedArray[i][k++] = arrayA[i][j];
}
for (int j = 0; j < arrayB[0].length; j++) {
mergedArray[i][k++] = arrayB[i][j];
}
k=0;
}
return mergedArray;
}
For my java class, I have this problem:
Write a program that generates 100 random integers in the range 0 to 25, and stores them in an array. Then, the program should call a class method that sorts the odd numbers into an array and returns the array. The program should then call another method that sorts the even numbers into a separate array and returns the array. Both arrays should then be displayed.
This is my code:
public class Assignment8
{
public static void main(String [] args)
{
int [] randomNums = new int [100];
for (int i = 0; i < randomNums.length; i++) {
randomNums[i] = (int) (Math.random() * 26);
int[] oddNums = sortOdd(randomNums);
System.out.println("The odd numbers are ");
for (int n = 0; n<=oddNums.length; n++) {
System.out.print(n);
}
int[] evenNums = sortEven(randomNums);
System.out.println("The even numbers are ");
for (int o = 0; o<=evenNums.length; o++) {
System.out.print(o);
}
}
}
public static int[] sortOdd(int[] randomNums)
{
int numOdds = 0;
for (int x : randomNums){
if(x % 2 == 1){
++numOdds;
}
}
int[] oddNums = new int[numOdds];
int z = 0;
for (int n : randomNums){
if(n % 2 == 1){
oddNums[z] = n;
z++;
}
}
return oddNums;
}
public static int[] sortEven(int[] randomNums)
{
int numEvens = 0;
for (int x : randomNums){
if(x % 2 == 0){
++numEvens;
}
}
int[] evenNums = new int[numEvens];
int z = 0;
for (int n : randomNums){
if(n % 2 == 0){
evenNums[z] = n;
z++;
}
}
return evenNums;
}
}
It is just printing out a bunch of numbers and the words "The even numbers are" and "The odd numbers are". What should I fix in my code to make it fulfill my assignment?
Your code seems fine, but you are missing a proper sort methodology, ascending or descending won't matter much, but the algorithm you choose to sort the array is unknown in this case. Let me introduce you to the worst method to sort an array, bubble-sort and there are many others like Insertion Sort, Merge Sort, QuickSort, BucketSort etc etc, built-in java methods can handle sorts at super fast speeds, but for the sake of simplicity, take bubble sort as the sorting method, this is how it looks in code
public static void sortArray( int[] data )
{
for( int x = 0; x < data.length; x++ )
{
for( int y = 0; y < data.length - 1; y++ )
{
if( data[y] < data[y + 1] )
{
int hold = data[y];
data[y] = data[y + 1];
data[y + 1] = hold;
}
}
}
}
Simply arranges the array in descending order. Now you would also like to generate a random array of fixed size, with elements no greater than 25. You should avoid your approach of generating such an array, because you are going to get simply 0's out of it, Math.random() is generating floating points, try this method to generate random array
public static int[] generateRandomArrayWithLimitAndSize( int limit , int size )
{
final java.util.Random rand = new java.util.Random();
final int[] data = new int[size];
for( int x = 0; x < data.length; x++ )
{
data[x] = rand.nextInt(limit);
}
return data;
}
Here is how you would have gone to sort even's
public static int[] sortEven( int[] data )
{
int len = 0;
int[] copyData;
for( int x = 0; x < data.length; x++ )
{
if( data[x] % 2 == 0 )
{
len++;
}
}
copyData = new int[len];
for( int x = 0 , y = 0; x < data.length; x++ )
{
if( data[x] % 2 == 0 )
{
copyData[y++] = data[x];
}
}
sortArray( copyData );
return copyData;
}
You can well imagine what the code for sortOdd should have looked like. Now you can try to visualize the result by trying this
public static void main(String[] args)
{
int[] myArray = generateRandomArrayWithLimitAndSize( 25 , 100 ); // limit,size
System.out.println( "Actual Array: " + java.util.Arrays.toString( myArray ) );
System.out.println( "\r\nSorting Evens: \r\n" + java.util.Arrays.toString( sortEven( myArray ) ) );
System.out.println( "\r\nSorting Odds: \r\n" + java.util.Arrays.toString( sortOdd( myArray ) ) );
}
And if you are still facing troubles in You can well imagine what the code for sortOdd should have looked like , then this is sortOdd(int[]) definition
public static int[] sortOdd( int[] data )
{
int len = 0;
int[] copyData;
for( int x = 0; x < data.length; x++ )
{
if( data[x] % 2 != 0 )
{
len++;
}
}
copyData = new int[len];
for( int x = 0 , y = 0; x < data.length; x++ )
{
if( data[x] % 2 != 0 )
{
copyData[y++] = data[x];
}
}
sortArray( copyData );
return copyData;
}
Open to further questions if any, but all this should work fine for you
import java.util.ArrayList;
import java.util.List;
public class Assignment8
{
public static void main(String [] args)
{
int [] randomNums = new int [100];
for (int i = 0; i < randomNums.length; i++)
{
randomNums[i] = (int) (Math.random() * 26);
System.out.println(randomNums[i] +"\n");
}
Integer[] oddNums = sortOdd(randomNums);
System.out.println("The odd numbers are ");
for (int n = 0; n< oddNums.length; n++)
{
System.out.print(oddNums[n] +"\n");
}
Integer[] evenNums = sortEven(randomNums);
System.out.println("The even numbers are ");
for (int o = 0; o< evenNums.length; o++)
{
System.out.print(evenNums[o] + "\n");
}
}
public static Integer[] sortOdd(int[] randomNums)
{
List<Integer> oddNums = new ArrayList<>();
for (int x : randomNums){
if(x % 2 == 1){
oddNums.add(x);
}
}
return oddNums.toArray(new Integer[oddNums.size()]);
}
public static Integer[] sortEven(int[] randomNums)
{
List<Integer> evenNums = new ArrayList<>();
for (int x : randomNums){
if(x % 2 == 0){
evenNums.add(x);
}
}
return evenNums.toArray(new Integer[evenNums.size()]);
}
}
I have an array of integers, and I need to find the one that's closest to zero (positive integers take priority over negative ones.)
Here is the code I have so far:
public class CloseToZero {
public static void main(String[] args) {
int[] data = {2,3,-2};
int curr = 0;
int near = data[0];
// find the element nearest to zero
for ( int i=0; i < data.length; i++ ){
curr = data[i] * data[i];
if ( curr <= (near * near) ) {
near = data[i];
}
}
System.out.println( near );
}
}
Currently I'm getting a result of -2 but I should be getting 2. What am I doing wrong?
This will do it in O(n) time:
int[] arr = {1,4,5,6,7,-1};
int closestIndex = 0;
int diff = Integer.MAX_VALUE;
for (int i = 0; i < arr.length; ++i) {
int abs = Math.abs(arr[i]);
if (abs < diff) {
closestIndex = i;
diff = abs;
} else if (abs == diff && arr[i] > 0 && arr[closestIndex] < 0) {
//same distance to zero but positive
closestIndex =i;
}
}
System.out.println(arr[closestIndex ]);
If you are using java8:
import static java.lang.Math.abs;
import static java.lang.Math.max;
public class CloseToZero {
public static void main(String[] args) {
int[] str = {2,3,-2};
Arrays.stream(str).filter(i -> i != 0)
.reduce((a, b) -> abs(a) < abs(b) ? a : (abs(a) == abs(b) ? max(a, b) : b))
.ifPresent(System.out::println);
}
}
Sort the array (add one line of code) so the last number you pick up will be positive if the same absolute value is selected for a positive and negative numbers with the same distance.
Source code:
import java.util.Arrays;
public class CloseToZero {
public static void main(String[] args) {
int[] data = {2,3,-2};
int curr = 0;
int near = data[0];
Arrays.sort(data); // add this
System.out.println(Arrays.toString(data));
// find the element nearest to zero
for ( int i=0; i < data.length; i++ ){
System.out.println("dist from " + data[i] + " = " + Math.abs(0 -data[i]));
curr = data[i] * data[i];
if ( curr <= (near * near) ) {
near = data[i];
}
}
System.out.println( near );
}
}
Just add zero to this list.
Then sort the list
Arrays.sort(data);
then grab the number before or after the zero and pick the minimum one greater than zero
Assumption is that the array data has at least 1 value.
int closestToZero = 0;
for ( int i = 1; i < data.length; i++ )
{
if ( Math.abs(data[i]) < Math.abs(data[closestToZero]) ) closestToZero = i;
}
The value in closestToZero is the index of the value closest to zero, not the value itself.
static int Solve(int N, int[] A){
int min = A[0];
for (int i=1; i<N ; i++){
min = min > Math.abs(0- A[i]) ? Math.abs(0- A[i]) : Math.abs(min);
}
return min;
}
As you multiply data[i] with data[i], a value negative and a value positive will have the same impact.
For example, in your example: 2 and -2 will be 4. So, your code is not able to sort as you need.
So, here, it takes -2 as the near value since it has the same "weight" as 2.
I have same answer with different method,Using Collections and abs , we can solved.
static int Solve(int N, int[] A){
List<Integer> mInt=new ArrayList<>();
for ( int i=0; i < A.length; i++ ){
mInt.add(Math.abs(0 -A[i]));
}
return Collections.min(mInt);
}
That all,As simple as that
This is a very easy to read O(n) solution for this problem.
int bigestNegative = Integer.MIN_VALUE;
int smalestpositive = Integer.MAX_VALUE;
int result = 0;
for (int i = 0; i < n; i++) {
//if the zero should be considered as result as well
if ( temperatures[i] == 0 ) {
result = 0;
break;
}
if ( temperatures[i] > 0 && temperatures[i] < smalestpositive ) {
smalestpositive = temperatures[i];
}
if ( temperatures[i] < 0 && temperatures[i] > bigestNegative ) {
bigestNegative = temperatures[i];
}
}
if( (Math.abs(bigestNegative)) < (Math.abs(smalestpositive)) && bigestNegative != Integer.MIN_VALUE)
result = bigestNegative;
else
result = smalestpositive;
System.out.println( result );
First convert the int array into stream. Then sort it with default sorting order. Then filter greater than zero & peek the first element & print it.
Do it in declarative style which describes 'what to do', not 'how to do'. This style is more readable.
int[] data = {2,3,-2};
IntStream.of(data)
.filter(i -> i>0)
.sorted()
.limit(1)
.forEach(System.out::println);
using Set Collection and abs methode to avoid complex algo
public static void main(String[] args) {
int [] temperature={0};
***// will erase double values and order them from small to big***
Set<Integer> s= new HashSet<Integer>();
if (temperature.length!=0) {
for(int i=0; i<temperature.length; i++) {
***// push the abs value to the set***
s.add(Math.abs(temperature[i]));
}
// remove a zero if exists in the set
while(s.contains(0)) {
s.remove(0);
}
***// get first (smallest) element of the set : by default it is sorted***
if (s.size()!=0) {
Iterator iter = s.iterator();
System.out.println(iter.next());
}
else System.out.println(0);
}
else System.out.println(0);
}
static int nearToZero(int[] A){
Arrays.sort(A);
int ans = 0;
List<Integer> list = Arrays.stream(A).boxed().collect(Collectors.toList());
List<Integer> toRemove = new ArrayList<>();
List<Integer> newList = new ArrayList<>();
for(int num: list){
if(newList.contains(num)) toRemove.add(num);
else newList.add(num);
}
list.removeAll(toRemove);
for(int num : list){
if(num == 0 ) return 0;
if(ans == 0 )ans = num;
if(num < 0 && ans < num) ans = num;
if(num < ans) ans = num;
if(num > 0 && Math.abs(ans) >= num) ans = num;
}
return ans;
}
here is a method that gives you the nearest to zero.
use case 1 : {1,3,-2} ==> return 1 : use the Math.abs() for comparison and get the least.
use case 2 : {2,3,-2} ==> return 2 : use the Math.abs() for comparison and get the Math.abs(least)
use case 3 : {-2,3,-2} ==> return -2: use the Math.abs() for comparison and get the least.
public static double getClosestToZero(double[] liste) {
// if the list is empty return 0
if (liste.length != 0) {
double near = liste[0];
for (int i = 0; i < liste.length; i++) {
// here we are using Math.abs to manage the negative and
// positive number
if (Math.abs(liste[i]) <= Math.abs(near)) {
// manage the case when we have two equal neagative numbers
if (liste[i] == -near) {
near = Math.abs(liste[i]);
} else {
near = liste[i];
}
}
}
return near;
} else {
return 0;
}
}
You can do like this:
String res = "";
Arrays.sort(arr);
int num = arr[0];
int ClosestValue = 0;
for (int i = 0; i < arr.length; i++)
{
//for negatives
if (arr[i] < ClosestValue && arr[i] > num)
num = arr[i];
//for positives
if (arr[i] > ClosestValue && num < ClosestValue)
num = arr[i];
}
res = num;
System.out.println(res);
First of all you need to store all your numbers into an array. After that sort the array --> that's the trick who will make you don't use Math.abs(). Now is time to make a loop that iterates through the array. Knowing that array is sorted is important that you start to make first an IF statement for negatives numbers then for the positives (in this way if you will have two values closest to zero, let suppose -1 and 1 --> will print the positive one).
Hope this will help you.
The easiest way to deal with this is split the array into positive and negative sort and push the first two items from both the arrays into another array. Have fun!
function closeToZeroTwo(arr){
let arrNeg = arr.filter(x => x < 0).sort();
let arrPos = arr.filter(x => x > 0).sort();
let retArr = [];
retArr.push(arrNeg[0], arrPos[0]);
console.log(retArr)
}
Easiest way to just sort that array in ascending order suppose input is like :
int[] array = {10,-5,5,2,7,-4,28,65,95,85,12,45};
then after sorting it will gives output like:
{-5,-4,2,5,7,10,12,28,45,65,85,95,}
and for positive integer number, the Closest Positive number is: 2
Logic :
public class Closest {
public static int getClosestToZero(int[] a) {
int temp=0;
//following for is used for sorting an array in ascending nubmer
for (int i = 0; i < a.length-1; i++) {
for (int j = 0; j < a.length-i-1; j++) {
if (a[j]>a[j+1]) {
temp = a[j];
a[j]=a[j+1];
a[j+1]=temp;
}
}
}
//to check sorted array with negative & positive values
System.out.print("{");
for(int number:a)
System.out.print(number + ",");
System.out.print("}\n");
//logic for check closest positive and Integer
for (int i = 0; i < a.length; i++) {
if (a[i]<0 && a[i+1]>0) {
temp = a[i+1];
}
}
return temp;
}
public static void main(String[] args) {
int[] array = {10,-5,5,2,7,-4,28,65,95,85,12,45};
int closets =getClosestToZero(array);
System.out.println("The Closest Positive number is : "+closets);
}
}
static void closestToZero(){
int[] arr = {45,-4,-12,-2,7,4};
int max = Integer.MAX_VALUE;
int closest = 0;
for (int i = 0; i < arr.length; i++){
int value = arr[i];
int abs = Math.abs(value);
if (abs < max){
max = abs;
closest = value;
}else if (abs == max){
if (value > closest){
closest = value;
}
}
}
Return a positive integer if two absolute values are the same.
package solution;
import java.util.Scanner;
public class Solution {
public static void trier(int tab[]) {
int tmp = 0;
for(int i = 0; i < (tab.length - 1); i++) {
for(int j = (i+1); j< tab.length; j++) {
if(tab[i] > tab[j]) {
tmp = tab[i];
tab[i] = tab[j];
tab[j] = tmp;
}
}
}
int prochePositif = TableauPositif(tab);
int procheNegatif = TableauNegatif(tab);
System.out.println(distanceDeZero(procheNegatif,prochePositif));
}
public static int TableauNegatif(int tab[]) {
int taille = TailleNegatif(tab);
int tabNegatif[] = new int[taille];
for(int i = 0; i< tabNegatif.length; i++) {
tabNegatif[i] = tab[i];
}
int max = tabNegatif[0];
for(int i = 0; i <tabNegatif.length; i++) {
if(max < tabNegatif[i])
max = tabNegatif[i];
}
return max;
}
public static int TableauPositif(int tab[]) {
int taille = TailleNegatif(tab);
if(tab[taille] ==0)
taille+=1;
int taillepositif = TaillePositif(tab);
int tabPositif[] = new int[taillepositif];
for(int i = 0; i < tabPositif.length; i++) {
tabPositif[i] = tab[i + taille];
}
int min = tabPositif[0];
for(int i = 0; i< tabPositif.length; i++) {
if(min > tabPositif[i])
min = tabPositif[i];
}
return min;
}
public static int TailleNegatif(int tab[]) {
int cpt = 0;
for(int i = 0; i < tab.length; i++) {
if(tab[i] < 0) {
cpt +=1;
}
}
return cpt;
}
public static int TaillePositif(int tab[]) {
int cpt = 0;
for(int i = 0; i < tab.length; i++) {
if(tab[i] > 0) {
cpt +=1;
}
}
return cpt;
}
public static int distanceDeZero(int v1, int v2) {
int absv1 = v1 * (-1);
if(absv1 < v2)
return v1;
else if(absv1 > v2)
return v2;
else
return v2;
}
public static void main(String[] args) {
int t[] = {6,5,8,8,-2,-5,0,-3,-5,9,7,4};
Solution.trier(t);
}
}
To maintain O(n) time complexity and getting the desired results we have to add another variable called 'num' and assign to it 'near' before changing it's value. And finally make necessary checks. The improvements in the code are are:
public class CloseToZero {
public static void main(String[] args) {
int[] data = {2,3,-2};
int curr = 0;
int near = data[0];
int num=near;
// find the element nearest to zero
for ( int i=0; i < data.length; i++ ){
curr = data[i] * data[i];
if ( curr <= (near * near) ) {
num=near;
near = data[i];
}
}
if(near<0 && near*(-1)==num)
near=num;
System.out.println( near );
}
}
We have to find the Closest number to zero.
The given array can have negative values also.
So the easiest approach would append the '0' in the given array and sort it and return the element next to '0'
append the 0
Sort the Array
Return the element next to 0.
`
N = int(input())
arr = list(map(int, input().split()))
arr.append(0)
arr.sort()
zeroIndex = arr.index(0)
print(arr[zeroIndex + 1])
--> If this solution leaves corner cases please let me know also.
`
if you don't wanna use the inbuilt library function use the below code (just an and condition with your existing code)-
public class CloseToZero {
public static void main(String[] args) {
int[] data = {2,3,-2,-1,1};
int curr = 0;
int near = data[0];
// find the element nearest to zero
for ( int i=0; i < data.length; i++ ){
curr = data[i] * data[i];
if ( curr <= (near * near) && !((curr - (near * near) == 0) && data[i] < 0)) {
near = data[i];
}
}
System.out.println( near );
}
}
!((curr - (near * near) == 0) && data[i] < 0) : skip asignment if if near and curr is just opposit in sign and the curr is negative
public static int find(int[] ints) {
if (ints==null) return 0;
int min= ints[0]; //a random value initialisation
for (int k=0;k<ints.length;k++) {
// if a positive value is matched it is prioritized
if (ints[k]==Math.abs(min) || Math.abs(ints[k])<Math.abs(min))
min=ints[k];
}
return min;
}
public int check() {
int target = 0;
int[] myArray = { 40, 20, 100, 30, -1, 70, -10, 500 };
int result = myArray[0];
for (int i = 0; i < myArray.length; i++) {
if (myArray[i] == target) {
result = myArray[i];
return result;
}
if (myArray[i] > 0 && result >= (myArray[i] - target)) {
result = myArray[i];
}
}
return result;
}
I have added a check for the positive number itself.
Please share your views folks!!
public class ClosesttoZero {
static int closZero(int[] ints) {
int result=ints[0];
for(int i=1;i<ints.length;i++) {
if(Math.abs(result)>=Math.abs(ints[i])) {
result=Math.abs(ints[i]);
}
}
return result;
}
public static void main(String[] args) {
// TODO Auto-generated method stub
int[] ints= {1,1,5,8,4,-9,0,6,7,1};
int result=ClosesttoZero.closZero(ints);
System.out.println(result);
}
}
It can be done simply by making all numbers positive using absolute value then sort the Array:
int[] arr = {9, 1, 4, 5, 6, 7, -1, -2};
for (int i = 0; i < arr.length; ++i)
{
arr[i] = Math.abs(arr[i]);
}
Arrays.sort(arr);
System.out.println("Closest value to 0 = " + arr[0]);
import java.math.*;
class Solution {
static double closestToZero(double[] ts) {
if (ts.length == 0)
return 0;
double closestToZero = ts[0];
double absClosest = Math.abs(closestToZero);
for (int i = 0; i < ts.length; i++) {
double absValue = Math.abs(ts[i]);
if (absValue < absClosest || absValue == absClosest && ts[i] > 0) {
closestToZero = ts[i];
absClosest = absValue;
}
}
return closestToZero;
}
}
//My solution priorizing positive numbers contraint
int closestToZero = Integer.MAX_VALUE;//or we
for(int i = 0 ; i < arrayInt.length; i++) {
if (Math.abs(arrayInt[i]) < closestToZero
|| Math.abs(closestToZero) == Math.abs(arrayInt[i]) && arrayInt[i] > 0 ) {
closestToZero = arrayInt[i];
}
}