I have an array of numbers, I want to delete k items such that they are next to each other such that the number of distinct elements in the array after deletion is maximum.
Example:
Input:
arr = [2,3,1,1,2]
k = 2
Ans: 3
Explanation:
Remove elements at index 3 & 4 which are 1 and 2 in array. Then array becomes [2,3,1] so it has 3 different elements.
This is my code:
int delete(int[] arr, int k) {
int n = arr.length;
int max = -1;
for (int i = 0; i < n - k + 1; i++) {
Set<Integer> set = new HashSet<>();
for (int j = 0; j < n; j++) {
if (i == j) {
j = j + k - 1;
} else {
set.add(arr[j]);
}
}
max = Math.max(set.size(), max);
}
return max;
}
How to reduce the time complexity for this problem. Because the size of array can be upto 1000000 and also the size of k is upto the array size. Each arraycelement can be upto 1000000
Here's a solution in O(N): It uses a map containing the number of occurrences of each number:
You start by filling the map with the elements from k to n-1 (in other words, the array without the first k elements), then you iterate and the first element and remove the last.
static int delete2(int[] arr, int k) {
int n = arr.length;
Map<Integer,Integer> map = new HashMap<>();
for (int i = k; i < n; i++) {
Integer value = arr[i];
if (!map.containsKey(value)) {
map.put(value, 1);
} else {
map.put(value, map.get(value)+1);
}
}
int max = map.size();
for (int i = 0; i < n-k; ++i) {
Integer value = arr[i];
if (!map.containsKey(value)) {
map.put(value, 1);
} else {
map.put(value, map.get(value)+1);
}
value = arr[i+k];
Integer count = map.get(value);
if (count == 1) {
map.remove(value);
} else {
map.put(value, count-1);
}
max = Math.max(map.size(), max);
}
return max;
}
If I understand correctly, you want to delete k adjacent elements such that the resulting set of set of arr - k elements is as large as possible.
Just test each candidate set (there are n sets to try).
So something like this should work
int delete(int[] arr, int k) {
int n = arr.length;
int max = -1;
Set<Integer> rem = new HashSet<>();
for (int i= 0; i<n; i++) {
rem.add(arr[i]);
}
for (int i = 0; i < n - k + 1; i++) {
Set<Integer> candidate = new HashSet<>();
for (int j = i; j < i + k; j++) {
candidate.add(arr[j]);
}
rem.removeAll(candidate);
if (rem.size() > max){
max = rem.size();
} else {
candidate.forEach((e) -> {
rem.add(e);
});
}
}
// you could also return the actual candidate set that produces the maximum
return max;
}
The set operation in the loop are all order k. So resulting time is order n*k.
int delete(int[] arr, int k) {
// step 1: traverse the array exactly once and make a hashtable
// with counts of each unique element
Map<Integer, Integer> elemCounts = new HashMap<>();
for (int e : arr) {
int ct = elemCounts.getOrDefault(e, 0);
elemCounts.put(e, ct + 1);
}
// step 2: traverse through the array exactly once more, and
// keep track of the adjacent elements which produce the least
// disturbance.
// step 2a: for the first k elements, see what removing them would
// do to the overall uniqueness of the array
int numPermanentRemovals = 0;
for (int i = 0; i < k; i++) {
int ct = elemCounts.get(arr[i]);
elemCounts.put(arr[i], ct - 1);
if (ct - 1 == 0) {
numPermanentRemovals += 1;
}
}
// step 2b: for the remainder of the array, track the rolling
// numPermanentRemovals for k adjacent elements
int minDisruption = numPermanentRemovals;
int minDisruptionIndex = 0;
for (int i = k; i < arr.length; i++) {
// put back the element at the start of the current window
int stct = elemCounts.get(arr[i - k]);
elemCounts.put(arr[i - k], stct + 1);
if (stct == 0) {
numPermanentRemovals -= 1;
}
// take out the element being added to the new window
int edct = elemCounts.get(arr[i]);
elemCounts.put(arr[i], edct - 1);
if (edct - 1 == 0) {
numPermanentRemovals += 1;
}
// if this minimum disruption index is a new floor, then
// replace the original
if (numPermanentRemovals < minDisruption) {
minDisruption = numPermanentRemovals;
minDisruptionIndex = i - k + 1;
}
// short-circuit if we find a perfect solution
if (minDisruption == 0) {
break;
}
}
return minDisruptionIndex;
}
Related
I'm trying to sort an array by the number of digits in each element from largest to smallest. This technically works but it seems to sort the array by value as well. For example, instead of printing out 1234 700 234 80 52, it should print 1234 234 700 52 80 as 234 is before 700 in the original array.
public class Sort {
public static void main(String[] args) {
//Initialize array
int [] arr = new int [] {52, 234, 80, 700, 1234};
int temp = 0;
//Displaying elements of original array
System.out.println("Elements of original array: ");
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i] + " ");
}
//Sort the array in descending order
//Math function is used to find length of each element
for (int i = 0; i < arr.length; i++) {
for (int j = i+1; j < arr.length; j++) {
if(Math.log10(arr[i]) + 1 < Math.log10(arr[j]) + 1) {
temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
}
System.out.println();
//Displaying elements of array after sorting
System.out.println("Elements of array sorted in descending order: ");
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i] + " ");
}
}
}
The easiest way to find the length of the number is to convert it into a String and then call the method length on it.
int number = 123;
String numberAsString = String.valueOf(number);
int length = numberAsString.length(); // returns 3
But you also could do it by division. The following method takes a number and divides by multiples of 10.
divide by 1 (we have at least a length of 1)
division by 10 > 0 (we have at least a length of 2)
division by 100 > 0 (we have at least a length of 3)
...
the variable i is used as dividend and the variable j is used as counter. j counts the length of the number.
As soon as number / i equals zero we return the counter value.
public int lengthOfNumber(int number) {
if (number == 0) {
return 1;
}
for (int i = 1, j = 0; ; i *= 10, j++) {
if (number / i == 0) {
return j;
}
}
}
There are multiple ways to sort the array. Here are some examples (I used the string version for comparing the values).
Use nested for-loop
public void sortArray(int[] array) {
for (int i = 0; i < array.length; i++) {
int swapIndex = -1;
int maxLength = String.valueOf(array[i]).length();
for(int j = i + 1; j < array.length; j++) {
int length2 = String.valueOf(array[j]).length();
if (maxLength < length2) {
maxLength = length2;
swapIndex = j;
}
}
if (swapIndex > -1) {
int temp = array[i];
array[i] = array[swapIndex];
array[swapIndex] = temp;
}
}
}
I used a variable swapIndex which is initialized with -1. This way we can avoid unnecessary array operations.
We take the first element in the outer for-loop and go through the rest of the array in the inner for-loop. we only save a new swapIndex if there is a number in the rest of the array with a higher length. if there is no number with a higher length, swapIndex remains -1. We do a possible swap only in the outer for-loop if necessary (if swapIndex was set).
Using Arrays.sort()
If you want to use Arrays.sort you need to convert your array from primitive type int to Integer.
public void sortArray(Integer[] array) {
Arrays.sort(array, (o1, o2) -> {
Integer length1 = String.valueOf(o1).length();
Integer length2 = String.valueOf(o2).length();
return length2.compareTo(length1);
});
}
Using a recursive method
public void sortArray(int[] array) {
for (int i = 0; i < array.length - 1; i++) {
String current = String.valueOf(array[i]);
String next = String.valueOf(array[i + 1]);
if (current.length() < next.length()) {
int temp = array[i];
array[i] = array[i + 1];
array[i + 1] = temp;
// here you do a recursive call
sortArray(array);
}
}
}
I have to solve an exercise with the following criteria:
Compare two arrays:
int[] a1 = {1, 3, 7, 8, 2, 7, 9, 11};
int[] a2 = {3, 8, 7, 5, 13, 5, 12};
Create a new array int[] with only unique values from the first array. Result should look like this: int[] result = {1,2,9,11};
NOTE: I am not allowed to use ArrayList or Arrays class to solve this task.
I'm working with the following code, but the logic for the population loop is incorrect because it throws an out of bounds exception.
public static int[] removeDups(int[] a1, int[] a2) {
//count the number of duplicate values found in the first array
int dups = 0;
for (int i = 0; i < a1.length; i++) {
for (int j = 0; j < a2.length; j++) {
if (a1[i] == a2[j]) {
dups++;
}
}
}
//to find the size of the new array subtract the counter from the length of the first array
int size = a1.length - dups;
//create the size of the new array
int[] result = new int[size];
//populate the new array with the unique values
for (int i = 0; i < a1.length; i++) {
int count = 0;
for (int j = 0; j < a2.length; j++) {
if (a1[i] != a2[j]) {
count++;
if (count < 2) {
result[i] = a1[i];
}
}
}
}
return result;
}
I would also love how to solve this with potentially one loop (learning purposes).
I offer following soulution.
Iterate over first array, and find out min and max it's value.
Create temporary array with length max-min+1 (you could use max + 1 as a length, but it could follow overhead when you have values e.g. starting from 100k).
Iterate over first array and mark existed values in temorary array.
Iterate over second array and unmark existed values in temporary array.
Place all marked values from temporary array into result array.
Code:
public static int[] getUnique(int[] one, int[] two) {
int min = Integer.MAX_VALUE;
int max = Integer.MIN_VALUE;
for (int i = 0; i < one.length; i++) {
min = one[i] < min ? one[i] : min;
max = one[i] > max ? one[i] : max;
}
int totalUnique = 0;
boolean[] tmp = new boolean[max - min + 1];
for (int i = 0; i < one.length; i++) {
int offs = one[i] - min;
totalUnique += tmp[offs] ? 0 : 1;
tmp[offs] = true;
}
for (int i = 0; i < two.length; i++) {
int offs = two[i] - min;
if (offs < 0 || offs >= tmp.length)
continue;
if (tmp[offs])
totalUnique--;
tmp[offs] = false;
}
int[] res = new int[totalUnique];
for (int i = 0, j = 0; i < tmp.length; i++)
if (tmp[i])
res[j++] = i + min;
return res;
}
For learning purposes, we won't be adding new tools.
Let's follow the same train of thought you had before and just correct the second part:
// populate the new array with the unique values
for (int i = 0; i < a1.length; i++) {
int count = 0;
for (int j = 0; j < a2.length; j++) {
if (a1[i] != a2[j]) {
count++;
if (count < 2) {
result[i] = a1[i];
}
}
}
}
To this:
//populate the new array with the unique values
int position = 0;
for (int i = 0; i < a1.length; i++) {
boolean unique = true;
for (int j = 0; j < a2.length; j++) {
if (a1[i] == a2[j]) {
unique = false;
break;
}
}
if (unique == true) {
result[position] = a1[i];
position++;
}
}
I am assuming the "count" that you implemented was in attempt to prevent false-positive added to your result array (which would go over). When a human determines whether or not an array contains dups, he doesn't do "count", he simply compares the first number with the second array by going down the list and then if he sees a dup (a1[i] == a2[j]), he would say "oh it's not unique" (unique = false) and then stop going through the loop (break). Then he will add the number to the second array (result[i] = a1[i]).
So to combine the two loops as much as possible:
// Create a temp Array to keep the data for the loop
int[] temp = new int[a1.length];
int position = 0;
for (int i = 0; i < a1.length; i++) {
boolean unique = true;
for (int j = 0; j < a2.length; j++) {
if (a1[i] == a2[j]) {
unique = false;
break;
}
}
if (unique == true) {
temp[position] = a1[i];
position++;
}
}
// This part merely copies the temp array of the previous size into the proper sized smaller array
int[] result = new int[position];
for (int k = 0; k < result.length; k++) {
result[k] = temp[k];
}
Making your code work
Your code works fine if you correct the second loop. Look at the modifications I did:
//populate the new array with the unique values
int counter = 0;
for (int i = 0; i < a1.length; i++) {
for (int j = 0; j < a2.length; j++) {
if (a1[i] == a2[j]) {
result[counter] = a1[i];
counter++;
}
}
}
The way I would do it
Now, here is how I would create a method like this without the need to check for the duplicates more than once. Look below:
public static int[] removeDups(int[] a1, int[] a2) {
int[] result = null;
int size = 0;
OUTERMOST: for(int e1: a1) {
for(int e2: a2) {
if(e1 == e2)
continue OUTERMOST;
}
int[] temp = new int[++size];
if(result != null) {
for(int i = 0; i < result.length; i++) {
temp[i] = result[i];
}
}
temp[temp.length - 1] = e1;
result = temp;
}
return result;
}
Instead of creating the result array with a fixed size, it creates a new array with the appropriate size everytime a new duplicate is found. Note that it returns null if a1 is equal a2.
You can make another method to see if an element is contained in a list :
public static boolean contains(int element, int array[]) {
for (int iterator : array) {
if (element == iterator) {
return true;
}
}
return false;
}
Your main method will iterate each element and check if it is contained in the second:
int[] uniqueElements = new int[a1.length];
int index = 0;
for (int it : a1) {
if (!contains(it, a2)) {
uniqueElements[index] = it;
index++;
}
}
How can I randomize arrayList
so that old index must not be the same as new index for all elements
for example
with a list with 3 items
after arrayList randomize
old index<->new index
1<-->2 <--different
2<-->1 <--different
3<-->3 <--same is not allowed
I want to make sure it will be
1<-->3 <--different
2<-->1 <--different
3<-->2 <--different
Collections.shuffle(List<?> list)
This should work with Lists which don't contain null values:
static <T> void shuffleList(List<T> list) {
List<T> temp = new ArrayList<T>(list);
Random rand = new Random();
for (int i = 0; i < list.size(); i++) {
int newPos = rand.nextInt(list.size());
while (newPos == i||temp.get(newPos)==null) {
newPos = rand.nextInt(list.size());
}
list.set(i, temp.get(newPos));
temp.set(newPos,null);
}
}
For list with null values:
static <T> void shuffleList(List<T> list) {
List<T> temp = new ArrayList<T>(list);
Integer [] indexes=new Integer[list.size()];
for (int i=0;i<list.size();i++){
indexes[i]=i;
}
Random rand = new Random();
for (int i = 0; i < list.size(); i++) {
int newPos = rand.nextInt(list.size());
while (newPos == i||indexes[newPos]==null) {
newPos = rand.nextInt(list.size());
}
list.set(i, temp.get(newPos));
indexes[newPos]=null;
}
}
That's something you have to implement yourself.
The shuffle is probably a series of random swaps (e.g. swap 1 -> 4,
swap 3 -> 2).
Keep track of each element's new position (e.g. 4 3 2
1 5 for a list with 5 elements and the above shuffle operations).
If any element is still at it's old place (5 in that example),
keep on shuffling.
Sounds like fun.
var numExist = [];
while(numExist.length!=array.length){
var randomizer = new Random();
int i =0;
var num = randomizer.nextInt(array.length);
if(!numExist.contains(num)){
array[i]=array[num];
numExist.add(num);
i++;
}
}
The following is a variation of Fisher-Yates which caters to the possibility that at least one item will remain in its original position.
The current Collections.shuffle() does not perform a complete randomization of the list.
public static void shuffle(List<Integer> list) {
Random r = new Random();
int size = list.size();
boolean flag = true;
for (int i = size - 1; i >= 0 && flag; i--) {
int pos = r.nextInt(i + 1);
if (list.get(i) == pos) {
if (i == 0) {
flag = false;
break;
}
// counter the upcoming decrement by incrementing i
i++;
continue;
}
int temp = list.get(i);
list.set(i, list.get(pos));
list.set(pos, temp);
}
// At this juncture, list.get(0) points to itself so choose a random candidate
// and swap them.
if (!flag) {
int pos = r.nextInt(size - 1) + 1;
int temp = list.get(0);
list.set(0, list.get(pos));
list.set(pos, list.get(0));
}
}
There may still be eventual problems but I used the following code to test the
shuffle with no problems detected.
for (int k = 0; k < 100000; k++) {
List<Integer> list =
IntStream.range(0, 52).boxed().collect(Collectors.toList());
System.out.println("Test run #" + k);
// Collections.shuffle(list);
shuffle(list);
for (int i = 0; i < list.size(); i++) {
if (i == list.get(i)) {
System.out.printf("Oops! List.get(%d) == %d%n", list.get(i), i);
}
}
}
So I need a way to find the mode(s) in an array of 1000 elements, with each element generated randomly using math.Random() from 0-300.
int[] nums = new int[1000];
for(int counter = 0; counter < nums.length; counter++)
nums[counter] = (int)(Math.random()*300);
int maxKey = 0;
int maxCounts = 0;
sortData(array);
int[] counts = new int[301];
for (int i = 0; i < array.length; i++)
{
counts[array[i]]++;
if (maxCounts < counts[array[i]])
{
maxCounts = counts[array[i]];
maxKey = array[i];
}
}
This is my current method, and it gives me the most occurring number, but if it turns out that something else occurred the same amount of times, it only outputs one number and ignore the rest.
WE ARE NOT ALLOWED TO USE ARRAYLIST or HASHMAP (teacher forbade it)
Please help me on how I can modify this code to generate an output of array that contains all the modes in the random array.
Thank you guys!
EDIT:
Thanks to you guys, I got it:
private static String calcMode(int[] array)
{
int[] counts = new int[array.length];
for (int i = 0; i < array.length; i++) {
counts[array[i]]++;
}
int max = counts[0];
for (int counter = 1; counter < counts.length; counter++) {
if (counts[counter] > max) {
max = counts[counter];
}
}
int[] modes = new int[array.length];
int j = 0;
for (int i = 0; i < counts.length; i++) {
if (counts[i] == max)
modes[j++] = array[i];
}
toString(modes);
return "";
}
public static void toString(int[] array)
{
System.out.print("{");
for(int element: array)
{
if(element > 0)
System.out.print(element + " ");
}
System.out.print("}");
}
Look at this, not full tested. But I think it implements what #ajb said:
private static int[] computeModes(int[] array)
{
int[] counts = new int[array.length];
for (int i = 0; i < array.length; i++) {
counts[array[i]]++;
}
int max = counts[0];
for (int counter = 1; counter < counts.length; counter++) {
if (counts[counter] > max) {
max = counts[counter];
}
}
int[] modes = new int[array.length];
int j = 0;
for (int i = 0; i < counts.length; i++) {
if (counts[i] == max)
modes[j++] = array[i];
}
return modes;
}
This will return an array int[] with the modes. It will contain a lot of 0s, because the result array (modes[]) has to be initialized with the same length of the array passed. Since it is possible that every element appears just one time.
When calling it at the main method:
public static void main(String args[])
{
int[] nums = new int[300];
for (int counter = 0; counter < nums.length; counter++)
nums[counter] = (int) (Math.random() * 300);
int[] modes = computeModes(nums);
for (int i : modes)
if (i != 0) // Discard 0's
System.out.println(i);
}
Your first approach is promising, you can expand it as follows:
for (int i = 0; i < array.length; i++)
{
counts[array[i]]++;
if (maxCounts < counts[array[i]])
{
maxCounts = counts[array[i]];
maxKey = array[i];
}
}
// Now counts holds the number of occurrences of any number x in counts[x]
// We want to find all modes: all x such that counts[x] == maxCounts
// First, we have to determine how many modes there are
int nModes = 0;
for (int i = 0; i < counts.length; i++)
{
// increase nModes if counts[i] == maxCounts
}
// Now we can create an array that has an entry for every mode:
int[] result = new int[nModes];
// And then fill it with all modes, e.g:
int modeCounter = 0;
for (int i = 0; i < counts.length; i++)
{
// if this is a mode, set result[modeCounter] = i and increase modeCounter
}
return result;
THIS USES AN ARRAYLIST but I thought I should answer this question anyways so that maybe you can use my thought process and remove the ArrayList usage yourself. That, and this could help another viewer.
Here's something that I came up with. I don't really have an explanation for it, but I might as well share my progress:
Method to take in an int array, and return that array with no duplicates ints:
public static int[] noDups(int[] myArray)
{
// create an Integer list for adding the unique numbers to
List<Integer> list = new ArrayList<Integer>();
list.add(myArray[0]); // first number in array will always be first
// number in list (loop starts at second number)
for (int i = 1; i < myArray.length; i++)
{
// if number in array after current number in array is different
if (myArray[i] != myArray[i - 1])
list.add(myArray[i]); // add it to the list
}
int[] returnArr = new int[list.size()]; // create the final return array
int count = 0;
for (int x : list) // for every Integer in the list of unique numbers
{
returnArr[count] = list.get(count); // add the list value to the array
count++; // move to the next element in the list and array
}
return returnArr; // return the ordered, unique array
}
Method to find the mode:
public static String findMode(int[] intSet)
{
Arrays.sort(intSet); // needs to be sorted
int[] noDupSet = noDups(intSet);
int[] modePositions = new int[noDupSet.length];
String modes = "modes: no modes."; boolean isMode = false;
int pos = 0;
for (int i = 0; i < intSet.length-1; i++)
{
if (intSet[i] != intSet[i + 1]) {
modePositions[pos]++;
pos++;
}
else {
modePositions[pos]++;
}
}
modePositions[pos]++;
for (int modeNum = 0; modeNum < modePositions.length; modeNum++)
{
if (modePositions[modeNum] > 1 && modePositions[modeNum] != intSet.length)
isMode = true;
}
List<Integer> MODES = new ArrayList<Integer>();
int maxModePos = 0;
if (isMode) {
for (int i = 0; i< modePositions.length;i++)
{
if (modePositions[maxModePos] < modePositions[i]) {
maxModePos = i;
}
}
MODES.add(maxModePos);
for (int i = 0; i < modePositions.length;i++)
{
if (modePositions[i] == modePositions[maxModePos] && i != maxModePos)
MODES.add(i);
}
// THIS LIMITS THERE TO BE ONLY TWO MODES
// TAKE THIS IF STATEMENT OUT IF YOU WANT MORE
if (MODES.size() > 2) {
modes = "modes: no modes.";
}
else {
modes = "mode(s): ";
for (int m : MODES)
{
modes += noDupSet[m] + ", ";
}
}
}
return modes.substring(0,modes.length() - 2);
}
Testing the methods:
public static void main(String args[])
{
int[] set = {4, 4, 5, 4, 3, 3, 3};
int[] set2 = {4, 4, 5, 4, 3, 3};
System.out.println(findMode(set)); // mode(s): 3, 4
System.out.println(findMode(set2)); // mode(s): 4
}
There is a logic error in the last part of constructing the modes array. The original code reads modes[j++] = array[i];. Instead, it should be modes[j++] = i. In other words, we need to add that number to the modes whose occurrence count is equal to the maximum occurrence count
Suppose I have an integer array like this:
{5,3,5,4,2}
and I have a method which returns the most common character
public int highestnumber(String[] num) {
int current_number = Integer.parseInt(num[0]);
int counter = 0;
for (int i = 1; i < num.length; ++i) {
if (current_number == Integer.parseInt(num[i])) {
++counter;
} else if (counter == 0) {
current_number = Integer.parseInt(num[i]);
++counter;
} else {
--counter;
}
}
return current_number;
}
but if I have multiple common character then i need to get the number which is closest to one(1), like if i have an array like this:
{5,5,4,4,2};
then the method should return 4, what should I do for this?
As per what I understand your question,
What you have to done is,
1. Create ArrayList from your int[]
2. Use HashMap for find duplicates, which one is unique
3. Sort it as Ascending order,
4. First element is what you want..
EDIT: Answer for your question
int[] arr = {5, 4, 5, 4, 2};
ArrayList<Integer> resultArray = new ArrayList<Integer>();
Set<Integer> set = new HashSet<Integer>();
for (int i = 0; i < arr.length; i++)
{
if (set.contains(arr[i]))
{
System.out.println("Duplicate value found at index: " + i);
System.out.println("Duplicate value: " + arr[i]);
resultArray.add(arr[i]);
}
else
{
set.add(arr[i]);
}
}
Collections.sort(resultArray);
for (int i = 0; i < resultArray.size(); i++)
{
Log.e("Duplicate Values:", resultArray.get(i) + "");
}
Your need is,
int values = resultArray.get(0);
Sort the array then count runs of values.
Fast way.
Create a counter int array one element for each number. Go through the array once and increment corresponding counter array for each number. Set highest number to first counter element then go through and change highest number to current element only if it is bigger than highest number, return highest number.
public int highestNumber(String[] num){
int[] count = new int[10];
int highest_number = 0;
int highest_value = 0;
for(int i = 0; i < num.length; i++)
count[Integer.parseInt(num[i])]++;;
for(int i = 0; i < count.length; i++)
if(count[i] > highest_value){
highest_number = i;
highest_value = count[i];
}
return highest_number;
}
10x slower but without other array.
Create three ints one for number and two for counting. Go through the array once for each int and increment current counting each time it shows up, if bigger that highest count, set to highest count and set highest number to current count. Return highest number.
public int highestNumber(String[] num){
int highest_number = 0;
int highest_value = 0;
int current_value = 0;
for(int i = 0; i < 10; i++){
for(int j = 0; j < num.length; j++)
if(i == Integer.parseInt(num[j]))
current_value++;
if(current_value > highest_value){
highest_value = current_value;
highest_number = i;
}
current_value = 0;
}
return highest_number;
}
The first is obviously much faster but if for whatever reason you don't want another array the second one works too.
You can also try this:
import java.util.TreeMap;
public class SmallestFrequentNumberFinder {
public static int[] stringToIntegerArray(String[] stringArray) {
int[] integerArray = new int[stringArray.length];
for (int i = 0; i < stringArray.length; i++) {
integerArray[i] = Integer.parseInt(stringArray[i]);
}
return integerArray;
}
public static int getSmallestFrequentNumber(int[] numbers) {
int max = -1;
Integer smallestFrequentNumber = null;
TreeMap<Integer, Integer> frequencyMaper = new TreeMap<Integer, Integer>();
for (int number : numbers) {
Integer frequency = frequencyMaper.get(number);
frequencyMaper.put(number, (frequency == null) ? 1 : frequency + 1);
}
for (int number : frequencyMaper.keySet()) {
Integer frequency = frequencyMaper.get(number);
if (frequency != null && frequency > max) {
max = frequency;
smallestFrequentNumber = number;
}
}
return smallestFrequentNumber;
}
public static void main(String args[]) {
String[] numbersAsString = {"5", "5", "4", "2", "4", "4", "2", "2"};
final int[] integerArray = stringToIntegerArray(numbersAsString);
System.out.println(getSmallestFrequentNumber(integerArray));
}
}