I have been trying to implement the given formula in JAVA but i was unsuccessful. Can someone help me find what I am doing wrong?
Do i need to shift the summation index and if so how?
My code:
public final class LinearSystem {
private LinearSystem() {
}
public static int[] solve(int [][]A , int []y) {
int n = A.length;
int[] x = new int[n];
for (int i = 0 ; i < n; i++) {
x[i] = 0;
int sum = 0;
for(int k = i + 1 ; k == n; k++) {
sum += A[i][k]*x[k]; // **java.lang.ArrayIndexOutOfBoundsException: Index 3 out of bounds for length 3**
}
x[i] = 1/A[i][i] * (y[i] - sum);
}
return x;
}
public static void main(String[] args) {
int[][]A = new int[][]{{2,-1,-3},{0,4,-1},{0,0,3}};
int [] y = new int[] {4,-1,23};
System.out.println(Arrays.toString(solve(A,y))); **// awaited result [2, -3, 1]**
}
}
Just trying to collect all my comments under the question into one coherent answer, since there are quite a few different mistakes in your program.
This method of solving linear equations relies on your calculating the components of the answer in reverse order - that is, from bottom to top. That's because each x[i] value depends on the values below it in the vector, but not on the values above it. So your outer loop, where you iterate over the x values needs to start at the biggest index, and work down to the smallest. In other words, instead of being for (int i = 0; i < n; i++), it needs to be for (int i = n - 1; i >= 0; i++).
The inner loop has the wrong stopping condition. With a for loop, the part between the two semicolons is the condition to continue iterating, not the condition to stop. So instead of for(int k = i + 1; k == n; k++), you need for(int k = i + 1; k < n; k++).
You're doing an integer division at the beginning of 1 / A[i][i] * (y[i] - sum);, which means the value is rounded to an integer before carrying on. When you divide 1 by another integer, you always get -1, 0 or 1 because of the rounding, and that makes your answer incorrect. The fix from point 4 below will deal with this.
The formula relies on the mathematical accuracy that comes with working with either floating point types or decimal types. Integers aren't going to be accurate. So you need to change the declarations of some of your variables, as follows.
public static double[] solve(double[][] A, double[] y)
double x[] = new double[n];
double sum = 0.0;
along with the corresponding changes in the main method.
First, you need the second loop to go until k < n, otherwise this throws the ArrayOutOfBounds Exceptions.
Second, you need to calculate your x in reverse order as #Dawood ibn Kareem said.
Also, you probably want x[] to be a double-array to not only get 0-values as result.
I am sorry I don't know much about math side so I couldn't fix it to the right solution but I noticed a few things wrong about your code.
1-You shouldn't initialize your arrays as integer arrays, because you will be doing integer division all over the place. For example 1/A[i][i] will result in 0 even if A[i][i] = 2
2-You shouldn't write k == n, if you do it like this then your for loop will only execute if k equals n, which is impossible for your case.
I think you want to do k < n, which loops from i+1 to the point where k = n - 1
Here is my code:
import java.util.Arrays;
public final class LinearSystem {
private LinearSystem() {
}
public static double[] solve(double [][]A , double []y) {
int n = A.length;
double[] x = new double[n];
for (int i = 0 ; i < n; i++) {
x[i] = 0;
int sum = 0;
for(int k = i + 1 ; k < n; k++) {
sum += A[i][k] * x[k]; // **java.lang.ArrayIndexOutOfBoundsException: Index 3 out of bounds for length 3**
}
x[i] = 1/A[i][i] * (y[i] - sum);
}
return x;
}
public static void main(String[] args) {
double[][]A = new double[][]{{2,-1,-3},{0,4,-1},{0,0,3}};
double [] y = new double[] {4,-1,23};
System.out.println(Arrays.toString(solve(A,y))); // awaited result [2, -3, 1]**
}
}
Remember that arrays are indexed from 0, so the last element is at index n - 1, not n.
Related
I've came across the following problem statement.
You have a list of natural numbers of size N and you must distribute the values in two lists A and B of size N/2, so that the squared sum of A elements is the nearest possible to the multiplication of the B elements.
Example:
Consider the list 7 11 1 9 10 3 5 13 9 12.
The optimized distribution is:
List A: 5 9 9 12 13
List B: 1 3 7 10 11
which leads to the difference abs( (5+9+9+12+13)^2 - (1*3*7*10*11) ) = 6
Your program should therefore output 6, which is the minimum difference that can be achieved.
What I've tried:
I've tried Greedy approach in order to solve this problem. I took two variables sum and mul. Now I started taking elements from the given set one by one and tried adding it in both the variables and calculated current
square of sum and multiplication. Now finalize the element in one of the two sets, such that the combination gives minimum possible value.
But this approach is not working in the given example itselt. I can't figure out what approach could be used here.
I'm not asking for exact code for the solution. Any possible approach and the reason why it is working, would be fine.
EDIT:
Source: CodinGame, Community puzzle
Try out this:
import java.util.Arrays;
public class Test {
public static void main(String [] args){
int [] arr = {7, 11, 1, 9, 10, 3, 5, 13, 9, 12};
int [][] res = combinations(5, arr);
int N = Arrays.stream(arr).reduce(1, (a, b) -> a * b);
int min = Integer.MAX_VALUE;
int [] opt = new int [5];
for (int [] i : res){
int k = (int) Math.abs( Math.pow(Arrays.stream(i).sum(), 2) - N/(Arrays.stream(i).reduce(1, (a, b) -> a * b)));
if(k < min){
min = k;
opt = i;
}
}
Arrays.sort(opt);
System.out.println("minimum difference is "+ min + " with the subset containing this elements " + Arrays.toString(opt));
}
// returns all k-sized subsets of a n-sized set
public static int[][] combinations(int k, int[] set) {
int c = (int) binomial(set.length, k);
int[][] res = new int[c][Math.max(0, k)];
int[] ind = k < 0 ? null : new int[k];
for (int i = 0; i < k; ++i) {
ind[i] = i;
}
for (int i = 0; i < c; ++i) {
for (int j = 0; j < k; ++j) {
res[i][j] = set[ind[j]];
}
int x = ind.length - 1;
boolean loop;
do {
loop = false;
ind[x] = ind[x] + 1;
if (ind[x] > set.length - (k - x)) {
--x;
loop = x >= 0;
} else {
for (int x1 = x + 1; x1 < ind.length; ++x1) {
ind[x1] = ind[x1 - 1] + 1;
}
}
} while (loop);
}
return res;
}
// returns n choose k;
// there are n choose k combinations without repetition and without observance of the sequence
//
private static long binomial(int n, int k) {
if (k < 0 || k > n) return 0;
if (k > n - k) {
k = n - k;
}
long c = 1;
for (int i = 1; i < k+1; ++i) {
c = c * (n - (k - i));
c = c / i;
}
return c;
}
}
Code taken from this stackoverflow answer, also take a look at this wikipedia article about Combinations.
I am not sure if there is any exact solution in polynomial time. But you could try a simulated annealing based approach.
My approach would be:
Initialize listA and listB to a random state
With probability p run greedy step, otherwise run a random step
Keep track of the state and corresponding error (with a HashMap)
Greedy step: Find one element you can move between the list that optimizes the error.
Random Step: Pick a random element from either of these two sets and calculate the error. If the error is better, keep it. Otherwise with probability of q keep it.
At either of these two steps make sure that the new state is not already explored (or at least discourage it).
Set p to a small value (<0.1) and q could depend on the error difference.
I'm trying to make an encryption program where the user enters a message and then converts the "letters into numbers".
For example the user enters a ABCD as his message. The converted number would be 1 2 3 4 and the numbers are stored into a one dimensional integer array. What I want to do is be able to put it into a 2x2 matrix with the use of two dimensional arrays.
Here's a snippet of my code:
int data[] = new int[] {10,20,30,40};
*for(i=0;i<2;i++)
{
for(j=0;j<2;j++)
{
for (int ctr=0; ictr<data.length(); ictr++){
a[i][j] = data[ctr];}
}
}
I know there's something wrong with the code but I am really lost.
How do I output it as the following?
10 20
30 40
(instead of just 10,20,30,40)
Here's one way of doing it. It's not the only way. Basically, for each cell in the output, you calculate the corresponding index of the initial array, then do the assignment.
int data[] = new int[] {10, 20, 30, 40, 50, 60};
int width = 3;
int height = 2;
int[][] result = new int[height][width];
for(int i = 0; i < height; i++) {
for(int j = 0; j < width; j++) {
result[i][j] = data[i * width + j];
}
}
Seems like you want to output a 2xn matrix while still having the values stored in a one-dimensional array. If that's the case then you can to this:
Assume the cardinality m of your set of values is known. Then, since you want it to be 2 rows, you calculate n=ceil(m/2), which will be the column count for your 2xn matrix. Note that if m is odd then you will only have n-1 values in your second row.
Then, for your array data (one-dimension array) which stores the values, just do
for(i=0;i<2;i++) // For each row
{
for(j=0;j<n;j++) // For each column,
// where index is baseline+j in the original one-dim array
{
System.out.print(data[i*n+j]);
}
}
But make sure you check the very last value for an odd cardinality set. Also you may want to do Integer.toString() to print the values.
Your code is close but not quite right. Specifically, your innermost loop (the one with ctr) doesn't accomplish much: it really just repeatedly sets the current a[i][j] to every value in the 1-D array, ultimately ending up with the last value in the array in every cell. Your main problem is confusion around how to work ctr into those loops.
There are two general approaches for what you are trying to do here. The general assumption I am making is that you want to pack an array of length L into an M x N 2-D array, where M x N = L exactly.
The first approach is to iterate through the 2D array, pulling the appropriate value from the 1-D array. For example (I'm using M and N for sizes below):
for (int i = 0, ctr = 0; i < M; ++ i) {
for (int j = 0; j < N; ++ j, ++ ctr) {
a[i][j] = data[ctr];
}
} // The final value of ctr would be L, since L = M * N.
Here, we use i and j as the 2-D indices, and start ctr at 0 and just increment it as we go to step through the 1-D array. This approach has another variation, which is to calculate the source index explicitly rather than using an increment, for example:
for (int i = 0; i < M; ++ i) {
for (int j = 0; j < N; ++ j) {
int ctr = i * N + j;
a[i][j] = data[ctr];
}
}
The second approach is to instead iterate through the 1-D array, and calculate the destination position in the 2-D array. Modulo and integer division can help with that:
for (int ctr = 0; ctr < L; ++ ctr) {
int i = ctr / N;
int j = ctr % N;
a[i][j] = data[ctr];
}
All of these approaches work. Some may be more convenient than others depending on your situation. Note that the two explicitly calculated approaches can be more convenient if you have to do other transformations at the same time, e.g. the last approach above would make it very easy to, say, flip your 2-D matrix horizontally.
check this solution, it works for any length of data
public class ArrayTest
{
public static void main(String[] args)
{
int data[] = new int[] {10,20,30,40,50};
int length,limit1,limit2;
length=data.length;
if(length%2==0)
{
limit1=data.length/2;
limit2=2;
}
else
{
limit1=data.length/2+1;
limit2=2;
}
int data2[][] = new int[limit1][limit2];
int ctr=0;
//stores data in 2d array
for(int i=0;i<limit1;i++)
{
for(int j=0;j<limit2;j++)
{
if(ctr<length)
{
data2[i][j] = data[ctr];
ctr++;
}
else
{
break;
}
}
}
ctr=0;
//prints data from 2d array
for(int i=0;i<limit1;i++)
{
for(int j=0;j<limit2;j++)
{
if(ctr<length)
{
System.out.println(data2[i][j]);
ctr++;
}
else
{
break;
}
}
}
}
}
this is the question, and yes it is homework, so I don't necessarily want anyone to "do it" for me; I just need suggestions: Maximum sum: Design a linear algorithm that finds a contiguous subsequence of at most M in a sequence of N long integers that has the highest sum among all such subsequences. Implement your algorithm, and confirm that the order of growth of its running time is linear.
I think that the best way to design this program would be to use nested for loops, but because the algorithm must be linear, I cannot do that. So, I decided to approach the problem by making separate for loops (instead of nested ones).
However, I'm really not sure where to start. The values will range from -99 to 99 (as per the range of my random number generating program).
This is what I have so far (not much):
public class MaxSum {
public static void main(String[] args){
int M = Integer.parseInt(args[0]);
int N = StdIn.readInt();
long[] a = new long[N];
for (int i = 0; i < N; i++) {
a[i] = StdIn.readLong();}}}
if M were a constant, this wouldn't be so difficult. For example, if M==3:
public class MaxSum2 {
public static void main(String[] args){
int N = StdIn.readInt(); //read size for array
long[] a = new long[N]; //create array of size N
for (int i = 0; i < N; i++) { //go through values of array
a[i] = StdIn.readLong();} //read in values and assign them to
//array indices
long p = a[0] + a[1] + a[2]; //start off with first 3 indices
for (int i =0; i<N-4; i++)
{if ((a[i]+a[i+1]+a[1+2])>=p) {p=(a[i]+a[i+1]+a[1+2]);}}
//if sum of values is greater than p, p becomes that sum
for (int i =0; i<N-4; i++) //prints the subsequence that equals p
{if ((a[i]+a[i+1]+a[1+2])==p) {StdOut.println((a[i]+a[i+1]+a[1+2]));}}}}
If I must, I think MaxSum2 will be acceptable for my lab report (sadly, they don't expect much). However, I'd really like to make a general program, one that takes into consideration the possibility that, say, there could be only one positive value for the array, meaning that adding the others to it would only reduce it's value; Or if M were to equal 5, but the highest sum is a subsequence of the length 3, then I would want it to print that smaller subsequence that has the actual maximum sum.
I also think as a novice programmer, this is something I Should learn to do. Oh and although it will probably be acceptable, I don't think I'm supposed to use stacks or queues because we haven't actually covered that in class yet.
Here is my version, adapted from Petar Minchev's code and with an important addition that allows this program to work for an array of numbers with all negative values.
public class MaxSum4 {
public static void main(String[] args)
{Stopwatch banana = new Stopwatch(); //stopwatch object for runtime data.
long sum = 0;
int currentStart = 0;
long bestSum = 0;
int bestStart = 0;
int bestEnd = 0;
int M = Integer.parseInt(args[0]); // read in highest possible length of
//subsequence from command line argument.
int N = StdIn.readInt(); //read in length of array
long[] a = new long[N];
for (int i = 0; i < N; i++) {//read in values from standard input
a[i] = StdIn.readLong();}//and assign those values to array
long negBuff = a[0];
for (int i = 0; i < N; i++) { //go through values of array to find
//largest sum (bestSum)
sum += a[i]; //and updates values. note bestSum, bestStart,
// and bestEnd updated
if (sum > bestSum) { //only when sum>bestSum
bestSum = sum;
bestStart = currentStart;
bestEnd = i; }
if (sum < 0) { //in case sum<0, skip to next iteration, reseting sum=0
sum = 0; //and update currentStart
currentStart = i + 1;
continue; }
if (i - currentStart + 1 == M) { //checks if sequence length becomes equal
//to M.
do { //updates sum and currentStart
sum -= a[currentStart];
currentStart++;
} while ((sum < 0 || a[currentStart] < 0) && (currentStart <= i));
//if sum or a[currentStart]
} //is less than 0 and currentStart<=i,
} //update sum and currentStart again
if(bestSum==0){ //checks to see if bestSum==0, which is the case if
//all values are negative
for (int i=0;i<N;i++){ //goes through values of array
//to find largest value
if (a[i] >= negBuff) {negBuff=a[i];
bestSum=negBuff; bestStart=i; bestEnd=i;}}}
//updates bestSum, bestStart, and bestEnd
StdOut.print("best subsequence is from
a[" + bestStart + "] to a[" + bestEnd + "]: ");
for (int i = bestStart; i<=bestEnd; i++)
{
StdOut.print(a[i]+ " "); //prints sequence
}
StdOut.println();
StdOut.println(banana.elapsedTime());}}//prints elapsed time
also, did this little trace for Petar's code:
trace for a small array
M=2
array: length 5
index value
0 -2
1 2
2 3
3 10
4 1
for the for-loop central to program:
i = 0 sum = 0 + -2 = -2
sum>bestSum? no
sum<0? yes so sum=0, currentStart = 0(i)+1 = 1,
and continue loop with next value of i
i = 1 sum = 0 + 2 = 2
sum>bestSum? yes so bestSum=2 and bestStart=currentStart=1 and bestEnd=1=1
sum<0? no
1(i)-1(currentStart)+1==M? 1-1+1=1 so no
i = 2 sum = 2+3 = 5
sum>bestSum? yes so bestSum=5, bestStart=currentStart=1, and bestEnd=2
sum<0? no
2(i)-1(currentStart)+1=M? 2-1+1=2 so yes:
sum = sum-a[1(curentstart)] =5-2=3. currentStart++=2.
(sum<0 || a[currentStart]<0)? no
i = 3 sum=3+10=13
sum>bestSum? yes so bestSum=13 and bestStart=currentStart=2 and bestEnd=3
sum<0? no
3(i)-2(currentStart)+1=M? 3-2+1=2 so yes:
sum = sum-a[1(curentstart)] =13-3=10. currentStart++=3.
(sum<0 || a[currentStart]<0)? no
i = 4 sum=10+1=11
sum>bestSum? no
sum<0? no
4(i)-3(currentStart)+1==M? yes but changes to sum and currentStart now are
irrelevent as loop terminates
Thanks again! Just wanted to post a final answer and I was slightly proud for catching the all negative thing.
Each element is looked at most twice (one time in the outer loop, and one time in the while loop).
O(2N) = O(N)
Explanation: each element is added to the current sum. When the sum goes below zero, it is reset to zero. When we hit M length sequence, we try to remove elements from the beginning, until the sum is > 0 and there are no negative elements in the beginning of it.
By the way, when all elements are < 0 inside the array, you should take only the largest negative number. This is a special edge case which I haven't written below.
Beware of bugs in the below code - it only illustrates the idea. I haven't run it.
int sum = 0;
int currentStart = 0;
int bestSum = 0;
int bestStart = 0;
int bestEnd = 0;
for (int i = 0; i < N; i++) {
sum += a[i];
if (sum > bestSum) {
bestSum = sum;
bestStart = currentStart;
bestEnd = i;
}
if (sum < 0) {
sum = 0;
currentStart = i + 1;
continue;
}
//Our sequence length has become equal to M
if (i - currentStart + 1 == M) {
do {
sum -= a[currentStart];
currentStart++;
} while ((sum < 0 || a[currentStart] < 0) && (currentStart <= i));
}
}
I think what you are looking for is discussed in detail here
Find the subsequence with largest sum of elements in an array
I have explained 2 different solutions to resolve this problem with O(N) - linear time.
I'm writing this Java program that finds all the prime numbers between a given range. Because I'm dealing with really big numbers my code seems to be not fast enough and gives me a time error. Here is my code, does anyone know to make it faster? Thanks.
import java.util.*;
public class primes2
{
private static Scanner streamReader = new Scanner(System.in);
public static void main(String[] args)
{
int xrange = streamReader.nextInt();
int zrange = streamReader.nextInt();
for (int checks = xrange; checks <= zrange; checks++)
{
boolean[] checkForPrime = Primes(1000000);
if (checkForPrime[checks])
{
System.out.println(checks);
}
}
}
public static boolean[] Primes(int n)
{
boolean[] isPrime = new boolean[n + 1];
if (n >= 2)
isPrime[2] = true;
for (int i = 3; i <= n; i += 2)
isPrime[i] = true;
for (int i = 3, end = sqrt(n); i <= end; i += 2)
{
if (isPrime[i])
{
for (int j = i * 3; j <= n; j += i << 1)
isPrime[j] = false;
}
}
return isPrime;
}
public static int sqrt(int x)
{
int y = 0;
for (int i = 15; i >= 0; i--)
{
y |= 1 << i;
if (y > 46340 || y * y > x)
y ^= 1 << i;
}
return y;
}
}
You'll get an enormous improvement just by changing this:
for (int checks = xrange; checks <= zrange; checks++)
{
boolean[] checkForPrime = Primes(1000000);
to this:
boolean[] checkForPrime = Primes(1000000);
for (int checks = xrange; checks <= zrange; checks++)
{
Your current code regenerates the sieve zrange - xrange + 1 times, but you actually only need to generate it once.
The obvious problem is that you're computing the primes up to 1000000 many time (zrange - xrange times). Another is that you dont need to compute the primes up to 1000000, you just need to check to primes up to zrange, so you're wasting time when zrange < 1000000, and getting a buffer overflow when zrange > 1000000.
You can start your inner loop from i*i, i.e. instead of for (int j = i * 3; j <= n; j += i << 1) you can write for (int j = i * i; j <= n; j += i << 1) for a minor speed-up.
Also, you have to be sure that your zrange is not greater than 1000000.
If xrange is much greater than sqrt(zrange), you can also split your sieve array in two, for an offset sieve scheme. The lower array will span from 2 to sqrt(zrange). The upper one will span from xrange to zrange. As you sieve your lower array, as each new prime becomes identified by it, inside your inner loop, in addition to marking the lower array up to its end also sieve the upper array. You will have to calcuate the starting offset for each prime i, and use the same step of 2*i as you do for the lower half. If your range is wider than a few primes, you will get speed advantage (otherwise just trial division by odds will suffice).
Another thing to try is, if evens > 2 are not primes anyway, why represent them in the array and waste half of the space? You can treat each i as representing an odd number, 2*i+1, thus compressing your array in half.
Last simple trick is to eliminate the multiples of 3 in advance as well, by marking ON not just odds (i.e. coprimes with 2), by { ... i+=2; ...}, but only coprimes with 2 and 3, by { ... i+=2; ... i+=4; ... } instead. Also, when marking OFF multiples of primes > 3, use { ... j+=2*i; ... j+=4i; ...} too. E.g., in 5*5, 5*7, 5*9, 5*11, ... you don't need to mark OFF 5*9, if no multiple of 3 was marked ON in the first place.
So I'm teaching myself algorithms from this book I purchased, and I have a pseudo-code for Finding the distance between the two closetst elements in an array of numbers
MinDistance(a[0...n-1])
Input: Array A of numbers
Output: Minimum Distance between two of its elements
dMin <- maximum integer
for i=0 to n-1 do
for j=0 to n-1 do
if i!=j and | A[i] - A[j] | < dMin
dMin = | A[i]-A[j] |
return dMin
However, I wanted to make improvements to this algorithmic solution. Change what's already there, or rewrite all together. Can someone help?
I wrote the function and class in Java to test the pseudo-code? Is that correct? And once again, how can I make it better from efficiency standpoint.
//Scanner library allowing the user to input data
import java.lang.Math.*;
public class ArrayTester{
//algorithm for finding the distance between the two closest elements in an array of numbers
public int MinDistance(int [] ar){
int [] a = ar;
int aSize = a.length;
int dMin = 0;//MaxInt
for(int i=0; i< aSize; i++)
{
for(int j=i+1; j< aSize;j++)
{
dMin = Math.min(dMin, Math.abs( a[i]-a[j] );
}
}
return dMin;
}
//MAIN
public static void main(String[] args){
ArrayTester at = new ArrayTester();
int [] someArray = {9,1,2,3,16};
System.out.println("NOT-OPTIMIZED METHOD");
System.out.println("Array length = "+ someArray.length);
System.out.println("The distance between the two closest elements: " + at.MinDistance(someArray));
} //end MAIN
} //END CLASS
SO I updated the function to minimize calling the Math.abs twice. What else can I do improve it. If I was to rewrite it with sort, would it change my for loops at all, or would it be the same just theoretically run faster.
public int MinDistance(int [] ar){
int [] a = ar;
int aSize = a.length;
int dMin = 0;//MaxInt
for(int i=0; i< aSize; i++)
{
for(int j=i+1; j< aSize;j++)
{
dMin = Math.min(dMin, Math.abs( a[i]-a[j] );
}
}
return dMin;
}
One obvious efficiency improvement: sort the integers first, then you can look at adjacent ones. Any number is going to be closest to its neighbour either up or down.
That changes the complexity from O(n2) to O(n log n). Admittedly for the small value of n shown it's not going to make a significant difference, but in terms of theoretical complexity it's important.
One micro-optimization you may want to make: use a local variable to store the result of Math.abs, then you won't need to recompute it if that turns out to be less than the minimum. Alternatively, you might want to use dMin = Math.min(dMin, Math.abs(a[i] - a[j])).
Note that you need to be careful of border conditions - if you're permitting negative numbers, your subtraction might overflow.
That's a naive solution of O(n^2).
Better way:
Sort the array, then go over it once more and check the distance between the sorted items.
This will work because they are in ascending order, so the number with the nearest value is adjacent.
That solution will be O(nlogn)
First of all, before making it fast, make it correct. Why is dmin initialized with the length of the array? If the array is [1, 1000], the result of your algorithm will be 2 instead of 999.
Then, why do you make j go from 0 to the length of the array? You compare each pair of elements twice. You should make j go from i + 1 to the length of the array (which will also avoid the i != j comparison).
Finally, you could gain a few nanoseconds by avoiding calling Math.abs() twice.
And then, you could completely change your algorithm by sorting the array first, as noted in other answers.
You can theoretically get an O(n) solution by
sorting with shell radix sort (edited, thanks to j_random_hacker for pointing it out)
one pass to find difference between numbers
Here's a question:
How long would it take to find the min distance if the array was sorted?
You should be able to finish the rest out from here.
Sorting the array first would exempt us from using another FOR loop.
public static int distclosest(int numbers[]) {
Arrays.sort(numbers);
int aSize = numbers.length;
int dMin = numbers[aSize-1];
for(int i=0; i<aSize-1; i++) {
dMin = Math.min(dMin, numbers[i+1]-numbers[i]);
}
return dMin;
}
static void MinNumber(int [] nums){
Arrays.sort(nums);
int min = nums[1] - nums[0];
int indexOne = 0 , indexTwo = 1;
for (int i = 1; i < nums.length -1; i++) {
if (min > (nums[i+1] - nums[i])) {
min = nums[i+1] - nums[i] ;
indexOne = i ;
indexTwo = i+1 ;
}
}
System.out.println("Minimum number between two values is: "+ min + " and the values is "+nums[indexOne]+" , "+nums[indexTwo] );
}
np: sorting the array is a must before executing the algorithm.
static int minDist(int arr[]) {
int firstPointer, nextPointer;
int minDistance = arr[1] - arr[0];
int tempDistance;
for (firstPointer = 0; firstPointer < arr.length; firstPointer++) {
for (nextPointer = firstPointer + 1; nextPointer < arr.length; nextPointer++) {
if (arr[nextPointer] == arr[firstPointer]) {
return 0;
} else {
tempDistance = (arr[nextPointer] - arr[firstPointer]);
if (minDistance > tempDistance) {
minDistance = tempDistance;
}
}
}
}
return minDistance;
}
public static void main(String[] args) {
int[] testArray = {1000, 1007, 3, 9, 21};
Arrays.sort(testArray);
int result = minDist(testArray);
System.out.println(result);
}