search many min in java [closed] - java

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 6 years ago.
Improve this question
i'm newbie in java. i have problem search many min in java.
i have a big data. but example data like this.
k[][] = [74 85 123
73 84 122
72 83 121
70 81 119
69 80 118
76 87 125
77 88 126
78 89 127];
and i want output like this.
min1 = 69 min1 = 80 min1 = 118
min2 = 70 min2 = 81 min2 = 119
min3 = 72 min3 = 83 min3 = 121
i use sorting in this data but the results it's not eficient.
someone help me
thx

Here is a general implementation using a helper class for finding the lowest X integers.
With three columns, three instances of the helper class is created, and the data is then iterated to collect the 3 lowest values for each column.
The advantages of this code are:
Only retains the lowest X values
Does not need to box the integers
Uses binary search for improved performance of higher values of X
This means it should be fast and have a low memory footprint, supporting unlimited amounts of data (if streamed).
See IDEONE for demo.
import java.util.Arrays;
class Ideone {
private static final int MIN_COUNT = 3;
public static void main(String[] args) {
int[][] data = { { 74, 85, 123 },
{ 73, 84, 122 },
{ 72, 83, 121 },
{ 70, 81, 119 },
{ 69, 80, 118 },
{ 76, 87, 125 },
{ 77, 88, 126 },
{ 78, 89, 127 } };
// Initialize min collectors
Min[] min = new Min[data[0].length];
for (int col = 0; col < min.length; col++)
min[col] = new Min(MIN_COUNT);
// Collect data
for (int row = 0; row < data.length; row++)
for (int col = 0; col < min.length; col++)
min[col].add(data[row][col]);
// Print result
for (int i = 0; i < MIN_COUNT; i++) {
for (int col = 0; col < min.length; col++)
System.out.printf("min%d = %-5d ", i + 1, min[col].get(i));
System.out.println();
}
}
}
class Min {
private int[] min;
public Min(int count) {
this.min = new int[count];
Arrays.fill(this.min, Integer.MAX_VALUE);
}
public void add(int value) {
int idx = Arrays.binarySearch(this.min, value);
if (idx != -this.min.length - 1) { // not insert at end
if (idx < 0)
idx = -idx - 1;
System.arraycopy(this.min, idx, this.min, idx + 1, this.min.length - idx - 1);
this.min[idx] = value;
}
}
public int get(int index) {
return this.min[index];
}
}

Say your data has N rows and M columns
Iterate over each column
Add all the elements in the column into a minHeap ( min priority queue)
Retrieve the first 3 numbers from the minHeap (these will be the 3 mins)
Clear the queue and move onto the next column
O(n) space, O(MNlg(N)) time

Related

How do you write a java program that generates the first 100 palindromic numbers (starting from 11, 22, etc), with 10 numbers per line

I know that you have to use a for loop, and I've narrowed it down to using the length of an integer to compare certain placements of said integer to determine if it's palindromic or not. How would you get the length of the integer though? I don't need a full code, I just need to know how you would get the length since I'm positive that what I'm thinking would work.
EDIT) I got it to work, but I have to separate 10 Palindrome numbers by each line. How does one do that? Should I share my code, if that helps?
Like this:
1,2,3,4,5,6,7,8,9,10
11,12,13,14,15,16,17,18,19,20
EDIT #2) I finished this, but I'm not sure whether I should close the question or delete it, since this seems to be a frequent question for others. Thanks, everybody! But, it works. I just reversed the number every loop, and if it equaled the originL, then it was palindromic.
Since we're posting code, I'll post mine. I don't think the op will just copy my code, but I hope he'll learn and copy my techniques.
Here are my test results.
11 22 33 44 55 66 77 88 99 101
111 121 131 141 151 161 171 181 191 202
212 222 232 242 252 262 272 282 292 303
313 323 333 343 353 363 373 383 393 404
414 424 434 444 454 464 474 484 494 505
515 525 535 545 555 565 575 585 595 606
616 626 636 646 656 666 676 686 696 707
717 727 737 747 757 767 777 787 797 808
818 828 838 848 858 868 878 888 898 909
919 929 939 949 959 969 979 989 999 1,001
I did exactly what I stated in my comment.
I created an int array of 100 elements.
I generated the first 100 palindromic integers.
I printed the 100 palindromic integers.
By breaking up the process into steps (methods), I was able to focus on one method at a time. I didn't write all the code before I ran the first test. I probably ran 10 tests or so before the code was complete.
Here's the complete runnable code.
import java.text.NumberFormat;
public class PalindromicIntegers {
public static void main(String[] args) {
new PalindromicIntegers().generatePalindromicIntegers();
}
public void generatePalindromicIntegers() {
printResults(generatePalindromes());
}
private int[] generatePalindromes() {
int[] palindromes = new int[100];
int value = 11;
int index = 0;
while (index < 100) {
if (isPalindrome(value)) {
palindromes[index++] = value;
}
value++;
}
return palindromes;
}
private void printResults(int[] palindromes) {
NumberFormat numberFormat = NumberFormat.getIntegerInstance();
String s = numberFormat.format(palindromes[palindromes.length - 1]);
int length = s.length() + 3;
String format = "%" + length + "s";
for (int i = 0; i < palindromes.length; i++) {
s = numberFormat.format(palindromes[i]);
System.out.print(String.format(format, s));
if ((i + 1) % 10 == 0) {
System.out.println();
}
}
}
private boolean isPalindrome(int value) {
StringBuilder builder = new StringBuilder();
String s = Integer.toString(value);
builder.append(s);
builder.reverse();
return builder.toString().equals(s);
}
}
I have to separate 10 Palindrome numbers by each line. How does one do
that?
Pick your favorite Palindrome Check, then use a simple loop. You can use the % Remainder Operator to determine when you've reached every 10th palindrome:
class Main {
public static void main(String[] args) {
int counter = 11; // start with the first length of 2 palindrome?
int palindromesFound = 0;
while (palindromesFound<100) {
if (isPalindrome(Integer.toString(counter))) {
System.out.print(counter);
palindromesFound++;
if (palindromesFound%10!=0) {
System.out.print(",");
}
else {
System.out.println("");
}
}
counter++;
}
}
// Andrew Mao: https://stackoverflow.com/a/15018381/2330053
public static boolean isPalindrome(String str) {
int n = str.length();
for( int i = 0; i < n/2; i++ )
if (str.charAt(i) != str.charAt(n-i-1)) return false;
return true;
}
}
Output:
11,22,33,44,55,66,77,88,99,101
111,121,131,141,151,161,171,181,191,202
212,222,232,242,252,262,272,282,292,303
313,323,333,343,353,363,373,383,393,404
414,424,434,444,454,464,474,484,494,505
515,525,535,545,555,565,575,585,595,606
616,626,636,646,656,666,676,686,696,707
717,727,737,747,757,767,777,787,797,808
818,828,838,848,858,868,878,888,898,909
919,929,939,949,959,969,979,989,999,1001
Using RxJava
import io.reactivex.rxjava3.core.Observable;
import io.reactivex.rxjava3.functions.Consumer;
public class Palindro {
private static boolean isPalindrome(int x) {
String s1 = String.valueOf(x);
StringBuilder r1 = new StringBuilder(s1).reverse();
return r1.toString().equals(s1);
}
public static void main(String[] args) {
Observable.range(11, Integer.MAX_VALUE - 10)
.filter(x -> isPalindrome(x))
.take(100)
.subscribe(new Printer());
}
}
class Printer implements Consumer<Integer> {
private int counter;
#Override
public void accept(Integer t) throws Throwable {
if (counter % 10 == 0) {
System.out.println();
}
System.out.printf("%d ", t);
counter++;
}
}
Just change the parameter to method take if you want less than or more than the first 100 number palindromes.
Some of the users have already provided pretty good solutions, but to make my answer helpful, I want to complete it, though.
So, I will use the same approach : iterating first half of the palindrome, and than adding adding it reversed from the left. But now I'll be iterating through all digit numbers alternating between odd and even number of digits, so we'll get all palindromes needed. Here is my code :
//Number of palindromes
int N = 100;
//Max number of symbols in the first half of palindrome divided by 2
int n = (int) Math.log10(N)/2;
//We'll print first 9 palindromes, that are out of algorithm
System.out.print("11, 22, 33, 44, 55, 66, 77, 88, 99, ");
N -= 9;
int min = 10, max = 100;
//Iterating through all number of digits.
//We'll keep track of number of palindromes using variable N,
//decreasing it every time we print new one.
for(int i = 1; i <= n; i++){
for(int j = min; j < max && N > 0; j++, N--){
String firstHalf = String.valueOf(j);
//Removing one symbol from second half to make digit number odd
String secondHalf = new StringBuilder(firstHalf).reverse().substring(1).toString();
System.out.print(firstHalf + secondHalf + ", ");
if(N%10 == 1) System.out.print("\n");
}
if(N <= 0) break;
for(int j = min; j < max && N > 0; j++, N--){
String firstHalf = String.valueOf(j);
String secondHalf = new StringBuilder(firstHalf).reverse().toString();
System.out.print(firstHalf + secondHalf + ", ");
if(N%10 == 1) System.out.print("\n");
}
min = max;
max *= 10;
}
Here is an easy way using streams.
iterate sequential integers starting with 11
convert to a string
only pass those that equal their reverse
limit to the first 100
collect in a list.
print
List<String> results = IntStream.iterate(11,i->i+1)
.mapToObj(Integer::toString)
.filter(a -> a.equals(
new StringBuilder(a).reverse().toString()))
.limit(100).collect(Collectors.toList());
for(int i = 0; i < results.size(); i+= 10) {
System.out.println(results.subList(i,i+10));
}
Prints
[11, 22, 33, 44, 55, 66, 77, 88, 99, 101]
[111, 121, 131, 141, 151, 161, 171, 181, 191, 202]
[212, 222, 232, 242, 252, 262, 272, 282, 292, 303]
[313, 323, 333, 343, 353, 363, 373, 383, 393, 404]
[414, 424, 434, 444, 454, 464, 474, 484, 494, 505]
[515, 525, 535, 545, 555, 565, 575, 585, 595, 606]
[616, 626, 636, 646, 656, 666, 676, 686, 696, 707]
[717, 727, 737, 747, 757, 767, 777, 787, 797, 808]
[818, 828, 838, 848, 858, 868, 878, 888, 898, 909]
[919, 929, 939, 949, 959, 969, 979, 989, 999, 1001]

Find The Longest Increasing Sequence in a 2 Dimensional Array [duplicate]

This question already has answers here:
How to determine the longest increasing subsequence using dynamic programming?
(20 answers)
Closed 5 years ago.
I've been working on this problem for awhile and couldn't come up with the solution; I hope you can help out..
I'm trying to find the longest increasing sequence of numbers. For example, if I have the following 4X4 array:
[![enter image description here][1]][1]
int [] nums = {
{97 , 47 , 56 , 36},
{35 , 57 , 41 , 13},
{89 , 36 , 98 , 75},
{25 , 45 , 26 , 17}
};
THE EXPECTED RESULT : return 8 and the LIS 17, 26, 36, 41, 47, 56, 57, 97
I don't have the answer to it yet, I'm trying to reach it.
17 (3,3)
26 (3,2)
36 (2,1)
41 (1,2)
47 (0,1)
56 (0,2)
57 (1,1)
97 (0,0)
I hope my example is clear enough..
This is my code; when I try to find the longest increasing path, it doesn't do it backward not diagonally. Can anyone help me please?
public class Solution2 {
static int[] dx = { 1, -1, 0, 0 };
static int[] dy = { 0, 0, 1, -1 };
public static int longestIncreasingPath(int[][] matrix) {
if (matrix.length == 0)
return 0;
int m = matrix.length, n = matrix[0].length;
int[][] dis = new int[m][n];
int ans = 0;
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
ans = Math.max(ans, dfs(i, j, m, n, matrix, dis));
}
}
return ans;
}
static int dfs(int x, int y, int m, int n, int[][] matrix, int[][] dis) {
if (dis[x][y] != 0)
return dis[x][y];
for (int i = 0; i < 4; i++) {
int nx = x + dx[i];
int ny = y + dy[i];
if (nx >= 0 && ny >= 0 && nx < m && ny < n && matrix[nx][ny] > matrix[x][y]) {
dis[x][y] = Math.max(dis[x][y], dfs(nx, ny, m, n, matrix, dis));
}
}
return ++dis[x][y];
}
public static void main(String[] args) {
int arr[][] = {
{ 97, 47, 56, 36 },
{ 35, 57, 41, 13 },
{ 89, 36, 98, 75 },
{ 25, 45, 26, 17 }
};
System.out.println(longestIncreasingPath(arr));
}
}
I assume we are looking for a strictly increasing sequence (this is not clear from the original problem description).
This problem can then be solved by a dynamic programming approach:
1) sort the cells by their value into decreasing order.
2) in decreasing order assign the length of the longest path starting at this cell:
2a) if you cannot reach any of the previously visited cells assign 1
2b) otherwise assign 1 + max(reachable previous cell)
When this is finished, the overall maximum is the length of the longest path. The path itself can also be found by remembering the max cell in step 2b).
In the example this gives:
0,3 2,1
cell 98 97 89 75 57 56 47 45 41 36 36 35 26 25 17 13
length 1 1 1 2 2 3 4 2 5 6 6 7 7 7 8 7
As far as I understand, you try to implement a depth-first search to find the longest path of increasing order. If so, first of all it is better to mark numbers you visited somehow. A convenient solution is an array. As far as the numbers are marked, you can use it to check whether the particular number has already been counted in an increasing sequence. This is as a little hint for you.
If you are still confused about a depth-first search, I would recommend to read the Depth-First Search Wikipedia page to get a better understanding of what the algorithm is all about.
HTH, Evgeniy

Get smallest t items from an array of integers of size n [duplicate]

What would be the best solution to find top N (say 10) elements in an unordered list (of say 100).
The solution which came in my head was to 1. sort it using quick sort, 2. get top 10.
But is there any better alternative?
The time could be reduced to linear time:
Use the selection algorithm, which effectively find the k-th element in a un-sorted array in linear time. You can either use a variant of quick sort or more robust algorithms.
Get the top k using the pivot got in step 1.
How about delegating everything to Java ;)
function findTopN(Array list, int n)
{
Set sortedSet<Integer> = new TreeSet<>(Comparators.naturalOrder());
// add all elements from list to sortedSet
// return the first n from sortedSet
}
I am not trying to say that this is the best way. I still think Yin Zhu's method of finding the kth largest element is the best answer.
If you're dealing with simple elements like fixed-length integers, then provided you can spare a memory buffer of the same size as the input data, sorting can be done in O(n) time using bucket or radix sorts, and this will be the fastest.
Although there are linear-time selection algorithms, the hidden constant is very high -- around 24. That means an O(nlog n) algorithm will be typically faster for fewer than several million elements.
Otherwise, in the general case when you can only compare 2 elements and determine which is greater, the problem is best solved by a heap data structure.
Suppose you want the top k of n items. All solutions based on fully sorting the data require O(nlog n) time, while using a heap requires only O(nlog k) time -- just build a heap on the first k elements, then keep adding an element and removing the maximum. This will leave you with a heap containing the smallest k elements.
Yes, you can do it in O(n) by just keeping a (sorted) running list of the top N. You can sort the running list using the regular library functions or a sorting network. E.g. a simple demo using 3, and showing which elements in the running list change each iteration.
5 2 8 7 9
i = 0
top[0] <= 5
i = 1
top[1] <= 2
i = 2
top[2] <= top[1] (2)
top[1] <= top[0] (5)
top[0] <= 8
i = 3
top[2] <= top[1] (5)
top[1] <= 7
i = 4
top[2] <= top[1] (7)
top[1] <= top[0] (8)
top[0] <= 9
The best solution is to use whatever facilities your chosen language provides which will make your life easier.
However, assuming this was a question more related to what algorithm you should choose, I'm going to suggest a different approach here. If you're talking about 10 from 100, you shouldn't generally worry too much about performance unless you want to do it many times per second.
For example, this C code (which is about as inefficient as I can make it without being silly) still takes well under a tenth of a second to execute. That's not enough time for me to even think about going to get a coffee.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define SRCSZ 100
#define DSTSZ 10
int main (void) {
int unused[SRCSZ], source[SRCSZ], dest[DSTSZ], i, j, pos;
srand (time (NULL));
for (i = 0; i < SRCSZ; i++) {
unused[i] = 1;
source[i] = rand() % 1000;
}
for (i = 0; i < DSTSZ; i++) {
pos = -1;
for (j = 0; j < SRCSZ; j++) {
if (pos == -1) {
if (unused[j]) {
pos = j;
}
} else {
if (unused[j] && (source[j] > source[pos])) {
pos = j;
}
}
}
dest[i] = source[pos];
unused[pos] = 0;
}
printf ("Source:");
for (i = 0; i < SRCSZ; i++) printf (" %d", source[i]);
printf ("\nDest:");
for (i = 0; i < DSTSZ; i++) printf (" %d", dest[i]);
printf ("\n");
return 0;
}
Running it through time gives you (I've formatted the output a bit to make it readable, but haven't affected the results):
Source: 403 459 646 467 120 346 430 247 68 312 701 304 707 443
753 433 986 921 513 634 861 741 482 794 679 409 145 93
512 947 19 9 385 208 795 742 851 638 924 637 638 141
382 89 998 713 210 732 784 67 273 628 187 902 42 25
747 471 686 504 255 74 638 610 227 892 156 86 48 133
63 234 639 899 815 986 750 177 413 581 899 494 292 359
60 106 944 926 257 370 310 726 393 800 986 827 856 835
66 183 901
Dest: 998 986 986 986 947 944 926 924 921 902
real 0m0.063s
user 0m0.046s
sys 0m0.031s
Only once the quantities of numbers become large should you usually worry. Don't get me wrong, I'm not saying you shouldn't think about performance. What you shouldn't do is spend too much time optimising things that don't matter - YAGNI and all that jazz.
As with all optimisation questions, measure don't guess!
You can use List and can guava's Comparators class to get the desired results. It is a highly optimized solution. Please see a sample below, which gets top 5 numbers. Api can be found here.
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collector;
import org.junit.Test;
import com.google.common.collect.Comparators;
import com.google.common.collect.Lists;
public class TestComparator {
#Test
public void testTopN() {
final List<Integer> numbers = Lists.newArrayList(1, 3, 8, 2, 6, 4, 7, 5, 9, 0);
final Collector<Integer, ?, List<Integer>> collector = Comparators.greatest(5,
Comparator.<Integer>naturalOrder());
final List<Integer> top = numbers.stream().collect(collector);
System.out.println(top);
}
}
Output: [9, 8, 7, 6, 5]
Well, you can create a heap from an unsorted array in O(n) time, and you can get the top element from the heap in O(log(n)) time. So your total runtime is O(n + k*log(n)).
Written below both selection sort and insertion sort implementations. For larger data set I suggest insetion sort better than selection sort
public interface FindTopValues
{
int[] findTopNValues(int[] data, int n);
}
Insertion Sort Implementation:
public class FindTopValuesInsertionSortImpl implements FindTopValues {
/**
* Finds list of the highest 'n' values in the source list, ordered naturally,
* with the highest value at the start of the array and returns it
*/
#Override
public int[] findTopNValues(int[] values, int n) {
int length = values.length;
for (int i=1; i<length; i++) {
int curPos = i;
while ((curPos > 0) && (values[i] > values[curPos-1])) {
curPos--;
}
if (curPos != i) {
int element = values[i];
System.arraycopy(values, curPos, values, curPos+1, (i-curPos));
values[curPos] = element;
}
}
return Arrays.copyOf(values, n);
}
}
Selection Sort Implementation:
public class FindTopValuesSelectionSortImpl implements FindTopValues {
/**
* Finds list of the highest 'n' values in the source list, ordered naturally,
* with the highest value at the start of the array and returns it
*/
#Override
public int[] findTopNValues(int[] values, int n) {
int length = values.length;
for (int i=0; i<=n; i++) {
int maxPos = i;
for (int j=i+1; j<length; j++) {
if (values[j] > values[maxPos]) {
maxPos = j;
}
}
if (maxPos != i) {
int maxValue = values[maxPos];
values[maxPos] = values[i];
values[i] = maxValue;
}
}
return Arrays.copyOf(values, n);
}
}
Yes there is a way to do better than quicksort. As pointed by Yin Zhu, you can search for kth largest element first and then use that element value as your pivot to split the array
I was asked for the same algorithm on the interview.
I done that, if somebody can compare that with fastest algorithm in Java - will be very useful.
public int[] findTopNValues(int[] anyOldOrderValues, int n) {
if (n < 0) {
return new int[]{};
}
if (n == 1) {
return new int[]{findMaxValue(anyOldOrderValues)};
}
int[] result = new int[n + 1];
for (int i = 0; i < Math.min(n, anyOldOrderValues.length); i++) {
result[i] = anyOldOrderValues[i];
}
Arrays.sort(result);
int max = result[0];
for (int i = n - 1; i < anyOldOrderValues.length; i++) {
int value = anyOldOrderValues[i];
if (max < value) {
result[n] = value;
Arrays.sort(result);
int[] result1 = new int[n + 1];
System.arraycopy(result, 1, result1, 0, n);
result = result1;
max = result[0];
}
}
return convertAndFlip(result, n);
}
public static int[] convertAndFlip(int[] integers, int n) {
int[] result = new int[n];
int j = 0;
for (int i = n - 1; i > -1; i--) {
result[j++] = integers[i];
}
return result;
}
and test for that:
public void testFindTopNValues() throws Exception {
final int N = 100000000;
final int MAX_VALUE = 100000000;
final int returnArray = 1000;
final int repeatTimes = 5;
FindTopValuesArraySorting arraySorting = new FindTopValuesArraySorting();
int[] randomArray = createRandomArray(N, MAX_VALUE);
for (int i = 0; i < repeatTimes; i++) {
long start = System.currentTimeMillis();
int[] topNValues = arraySorting.findTopNValues(randomArray, returnArray);
long stop = System.currentTimeMillis();
System.out.println("findTopNValues() from " + N + " elements, where MAX value=" + (MAX_VALUE - 1) + " and return array size " + returnArray + " elements : " + (stop - start) + "msec");
// System.out.println("Result list = " + Arrays.toString(topNValues));
}
}
private static int[] createRandomArray(int n, int maxValue) {
Random r = new Random();
int[] arr = new int[n];
for (int i = 0; i < n; i++) {
arr[i] = r.nextInt(maxValue);
}
return arr;
}
Result is something like:
findTopNValues() from 100000000 elements, where MAX value=99999999 and return array size 1000 elements : 395msec
findTopNValues() from 100000000 elements, where MAX value=99999999 and return array size 1000 elements : 311msec
findTopNValues() from 100000000 elements, where MAX value=99999999 and return array size 1000 elements : 473msec
findTopNValues() from 100000000 elements, where MAX value=99999999 and return array size 1000 elements : 380msec
findTopNValues() from 100000000 elements, where MAX value=99999999 and return array size 1000 elements : 406msec
~400msc average result, for getting 1000 max integers from array of 100.000.000 initial elements.
not bad!
Just tried that set from above:
findTopNValues() from 101 elements and return array size 10 elements : 1msec
Result list = [998, 986, 986, 986, 947, 944, 926, 924, 921, 902]
Original list = [403, 459, 646, 467, 120, 346, 430, 247, 68, 312, 701, 304, 707, 443, 753, 433, 986, 921, 513, 634, 861, 741, 482, 794, 679, 409, 145, 93, 512, 947, 19, 9, 385, 208, 795, 742, 851, 638, 924, 637, 638, 141, 382, 89, 998, 713, 210, 732, 784, 67, 273, 628, 187, 902, 42, 25, 747, 471, 686, 504, 255, 74, 638, 610, 227, 892, 156, 86, 48, 133, 63, 234, 639, 899, 815, 986, 750, 177, 413, 581, 899, 494, 292, 359, 60, 106, 944, 926, 257, 370, 310, 726, 393, 800, 986, 827, 856, 835, 66, 183, 901]
The best Algorithm would by large depend on the size of K.
If K is small then by simply following BubbleSort Algorithm and iterating the outer loop K times
would give the top K values.
The complexity will be O(n*k).
However for values of K close to n the complexity will approach O(n^2). In such scenario quicksort might be a good alternative.
public class FindTopValuesSelectionSortImpl implements FindTopValues {
/**
* Finds list of the highest 'n' values in the source list, ordered naturally,
* with the highest value at the start of the array and returns it
*/
#Override
public int[] findTopNValues(int[] values, int n) {
int length = values.length;
for (int i=0; i<=n; i++) {
int maxPos = i;
for (int j=i+1; j<length; j++) {
if (values[j] > values[maxPos]) {
maxPos = j;
}
}
if (maxPos != i) {
int maxValue = values[maxPos];
values[maxPos] = values[i];**strong text**
values[i] = maxValue;
}
}
return Arrays.copyOf(values, n);
}
}
find-top-n-elements-in-an-array can be solved with below technique
Let's say array length is m
Using 2 loops like Bubble sort - O(m^2) 2 loops
Finding pivot at Nth position( Quick sort) -- finding pivot at nth location but worst case complexity is O(MLogM) and might lead to O(M^2)
Heap - Heap is very useful data-structure for such requirement like getKthMax, getKthMin, getTopN, getBottomN and so on..
Heap can be max heap or min heap and as per requirement one of them can be used.
In current scenario MinHeap makes more sense as minimum number will be always on top, with below steps to solve
Iterate over elements in the array
add element in heap
if heap size > n then pop one element from heap so any time heap will have at most n elements in the heap
Iterate over heap, and collect all element in collection
Time complexity:
m - size of array, n is top n element
O(MlogN) -- heap add and remove takes logN time and we are doing this for all element in the array
Space complexity O(N)
// Sample Java code
public List<Integer> getTopNElements(int[] arr, int n){
List<Integer> topNList = new ArrayList<>();
if(arr==null || arr.length <1 || n<1) return topNList;
PriorityQueue<Integer> heap = new PriorityQueue<>(); // default MinHeap
for(int elem: arr){
heap.offer(elem);
if(heap.size() >n) heap.poll();
}
while(!heap.isEmpty()){
topNList.add(heap.poll());
}
return topNList;
}
Hope this helps.

Random Number Generator of Even and Odd Numbers

I need to create an application that generates 25 random integers between 0 and 99 and then outputs those integers on two separate lines one for odd numbers and one for even numbers. I will need to use one array for even numbers and one for odd numbers. This is what I have so far:
public static void main(String[] args) {
//Odd Numbers
int[] oddNums = new int[25];
for (int index = 0; index < oddNums.length; index++) {
oddNums[index] = (int) (Math.random()*99);
}
System.out.print("ODD: ");
for (int index = 0; index < oddNums.length; index++) {
System.out.print(oddNums[index] + " ");
}
//Even Numbers
int[] evenNums = new int[25];
for (int index = 0; index < evenNums.length; index++) {
evenNums[index] = (int) (Math.random()*99);
}
System.out.print("\nEVEN: ");
for (int index = 0; index < evenNums.length; index++) {
System.out.print(evenNums[index] + " ");
}
}
I have set up the program to print out 25 random integers, but I do not know how I am going to get the program to print out only even numbers on one line and odd numbers on another (I am new to java).
Here is a sample output I am getting:
ODD: 28 36 54 98 35 1 59 43 96 69 41 66 37 15 30 17 29 67 56 83 71 4
24 70 38
EVEN: 34 45 36 26 73 84 60 39 21 49 28 98 69 14 32 24 72 29 26 88 77 2
23 58 47
This is wrong since there are both even and odd numbers on both lines.
This is what the output should look like:
ODD: 25 97 23 45 63 91 13 47 93 51 29
EVEN: 22 94 46 74 18 48 32 84 28 92 56
There are only odd numbers on one line and even numbers on another line.
Does anyone know what I need to add here?
A little modification to your program will yield the desired result.
public static void main(String[] args) {
//Odd Numbers
int[] randomNumbers = new int[25];
int[] evenNumbers = new int[25];
int[] oddNumbers = new int[25];
int k = 0, l = 0;
for (int index = 0; index < randomNumbers.length; index++) {
randomNumbers[index] = (int) (Math.random() * 99);
}
for (int i = 0; i < 25; i++) {
if (randomNumbers[i] % 2 == 0) {
evenNumbers[k] = randomNumbers[i];
k++;
} else {
oddNumbers[l] = randomNumbers[i];
l++;
}
}
}
You can generate an even number uniformly at random in [0,100] with the formula n = 2*x where x is uniformly random in [0, 49].
You can similarly generate an uniformly random odd number with n = 2*x+1 where x is uniformly random in [0,49].
You can just generate the 25 number. After generating those ints, you can locate them in the array they belong.
int num;
int oddIndex = -1;
int evenIndex = -1;
for (index = 0; index < 25 ; index++){
num = (int) (Math.random()*99);
if (num % 2 == 1){
oddIndex++;
oddNum[oddIndex] = num;
}
else{
evenIndex++;
evenNum[evenIndex] = num;
}
}
In this case, you're not sure about the sizes of each array. So, I advise you to use ArrayList instead of array. If you use an ArrayList, you won't need to deal with oddIndex and evenIndex.
Firstly,The random function you have written will be generating random numbers between 0 and 99. It will not be considering whether the numbers are odd or even.
If there is no restriction on the number of odd numbers and number of even numbers, just use the random generator once and depending on whether it is odd or even place it in the correct array.
For doing so, use the MOD operator i.e. check for remainder after dividing by 2 to see odd or even
At some point in your code, you need to have something like,
Pseudocode:
if (nextNumber is odd) then
put nextNumber at end of ODD array
else
put nextNumber at end of EVEN array
endif
You should also have a look at util.Random.nextInt() which is preferable for generating random integers.
Here's a solution that uses Java 8 streams:
public class NumberGenerator {
public static void main(String[] args) {
Random random = new Random();
int[] ints = random.ints(25, 0, 99).sorted().toArray();
int[] even = IntStream.of(ints).filter(x -> x % 2 == 0).toArray();
int[] odd = IntStream.of(ints).filter(x -> x % 2 == 1).toArray();
System.out.println(Arrays.toString(even));
System.out.println(Arrays.toString(odd));
}
}
First an array of all random integers are being created. 25 random integers are created and they should all be between 0 and 99.
The evens and odds are filtered out into two separate arrays.
[0, 4, 6, 16, 18, 22, 40, 42, 58, 64, 82, 84, 98]
[7, 27, 29, 31, 35, 55, 73, 75, 75, 79, 83, 91]

Subtract elements in an array

I have an array with this values 80 82 84 90 94 is it possible to subtract the values so the output could be 0 2 2 6 4?
I´ve edited the question:Now I want to use this in an android cursor adapter but I´m getting index out of bounds when it reaches the calculation of the difference.
public void bindView(View view, Context context, Cursor cursor) {
// here we are setting our data
// that means, take the data from the cursor and put it in views
double weight = cursor.getDouble(cursor
.getColumnIndex(DbHelper.ENTRY_USER_WEIGHT));
int count=cursor.getCount();
Double[] input = new Double[count];
// Obtaining the number of records
System.out.println("number of records "+input.length);
// Array for storing differences
double[] difference= new double[count ];
difference [0] = 0; // First record difference is 0 only
int i;
// Looping number of records times
for( i=0; i<count-1 ;i++)
{
input[i]=weight;
System.out.println("i value"+i);
System. out.println(""+input[i]);
// Difference = next record - current record
difference [i]= input [i+1] - input[i];
// System.out.println ("Difference between "+input [i+1]+ " and "+input[i] + " is : " +difference[i]);
}
// Setting the input array.
int input[]= {80, 82, 84, 90, 94};
// Obtaining the number of records
int noOfRecords = input.length;
// Array for storing differences
double[] difference= new double[noOfRecords ];
difference [0] = 0; // First record difference is 0 only
// Looping number of records times
for( int i=0; i < noOfRecords -1 ;i++)
{
// Difference = next record - current record
difference [i+1]= input [i+1] - input[i];
System.out.println ("Difference between "+input [i+1]+ " and "+input[i] + " is : " +difference[i+1]);
}
System.out.println("My final difference array Output is : "+java.util.Arrays.toString( difference ));
OUTPUT:
Difference between 82 and 80 is : 2.0
Difference between 84 and 82 is : 2.0
Difference between 90 and 84 is : 6.0
Difference between 94 and 90 is : 4.0
My final difference array Output is : [0.0, 2.0, 2.0, 6.0, 4.0]
If you replace double[] difference = new double[noOfRecords ]; by
int [] difference = new int [noOfRecords];
You get an output exactly as you wanted :
Difference between 82 and 80 is : 2
Difference between 84 and 82 is : 2
Difference between 90 and 84 is : 6
Difference between 94 and 90 is : 4
My difference array Output is : [0, 2, 2, 6, 4]
Logic:
for array Arr[] = {80 82 84 90 94}
Required output = {0,2,2,6,4}
Sol:
output[0] = 0;
for( i=1;i<cursor.getCount();i++)
{
output[i] = Arr[i]-Arr[i-1];
}
Note that the output array elements are obtained by subtracting current index element with the element at previous index.
Example 82-80 =2, 84-82=2, 90-84=6 and 94-90=4
You can subtract a number from its next number.
int[] numbers={80, 82, 84, 90, 94};
for (int i = 0; i < numbers.length; i++) {
if(i < numbers.length - 1)
System.out.println(numbers[i + 1] - numbers[i]);
}
}
Output-
2
2
6
4

Categories