Java - Find maximum number of duplicates within an array - java

I am utilizing a HashSet for finding the maximum number of duplicates of a value in a sorted Integer array. But my algorithm doesn't seem to work, not returning the desired results.
Set variables storing the number of duplicates found (0), and the maximum number of duplicates (0).
Set a HashSet that stores the unique values of an array.
Sort the array to be ready for comparison.
Loop through each value of the array
If the HashSet of unique values contains the current value:
Increment the duplicate Count
If the currentValue is not equal to the previous value:
If the duplicateCount is greater than the maximum Count:
maximumCount becomes duplicateCount
Reset duplicateCount to 0
Java Code:
HashSet<Integer> uniqueValues = new HashSet<Integer>(valueSequenceList);
int duplicateCount = 0;
int maxCount = 0;
Arrays.sort(valueSequence);
for (int i = 0; i < valueSequence.length; i++)
{
if (uniqueValues.contains(valueSequence[i]))
{
duplicateCount++;
}
if (i > 0 && valueSequence[i] != valueSequence[i-1])
{
if (duplicateCount > maxCount)
{
maxCount = duplicateCount;
duplicateCount = 0;
}
}
}
Example:
Input: [4, 4, 10, 4, 10]
Output: 4 Duplicates (There are supposed to be a maximum of 3 duplicates - Total number of values that are the same).

This is the Element Distinctness Problem - which is explained with details in the thread: Find duplicates in an array.
The mentiones thread discusses solutions to the problem, and shows lower bounds as well (cannot be done better than O(nlogn) without using a hash table.
So, if your data is not sorted - you could sort and iterate (as follows), or use a hash set - and then you don't need to sort the array.
If you first sort the array, or the array is already sorted, a single iteration will do:
Single iteration on a sorted array:
if (arr == null || arr.length == 0) return 0;
int last = arr[0];
int numDupes = 1;
for (int i = 1; i < arr.length; i++) {
if (arr[i] == last) numDupes++;
last = arr[i];
}
Using a HashSet (no need to sort):
if (arr == null) return 0;
Set<Integer> set = new HashSet<>();
int numDupes = 0;
for (int x : arr) {
if (set.contains(x)) numDupes++;
set.add(x);
}
If you are looking for the maximal number some element repeats (and not total number of repeats), you can use the same approach but slightly different:
Hashing solution - use a histogram:
Map<Integer,Integer> histogram = new HashMap<>();
for (int x : arr) {
if (!histogram.containsKey(x)) histogram.put(x,1);
else histogram.put(x,histogram.get(x) + 1);
}
int max = 0;
for (int x : histogram.values) max = max > x ? max : x;
return max;
Sorted array solution:
if (arr == null || arr.length == 0) return 0;
int last = arr[0];
int max = 0;
int currNumDupes = 1;
for (int i = 1; i < arr.length; i++) {
if (arr[i] == last) currNumDupes++;
else {
max = max > currNumDupes ? max : currNumDupes;
currNumDupes = 1;
}
last = arr[i];
}
max = max > currNumDupes ? max : currNumDupes; //if the most dupes is from the highest element

check the following code which returns the max count of duplicates
public static void main(String args[]) {
int[] inputArray = { 4, 4, 10, 4, 10 };
Map<Integer, Integer> hMap = new HashMap<Integer, Integer>();
HashSet<Integer> hSet = new HashSet<Integer>();
for (int i : inputArray) {
if (hSet.add(i)) {
hMap.put(i, 1);
} else {
hMap.put(i, hMap.get(i) + 1);
}
}
Iterator<Integer> iter = hMap.values().iterator();
int temp = 0;
while (iter.hasNext()) {
int max = iter.next();
if (max > temp) {
temp = max;
}
}
System.out.println(temp);
}

Suggestion:
You could use a simple Map<Integer, Integer> where the key is the item value, and the value is the count of that item.
This would make the code simple - no need to sort:
Map<Integer, Integer> count = new HashMap<Integer, Integer>();
for (Integer item : list){
if (count.containsKey(item)){
// increate count
count.put(item, count.get(key) + 1);
} else {
// no item yet - set count to 1
count.put(item, 1);
}
}
You could now use something like Collections.max to find the maximum Integer value on count.values() - or even write a Comparator<Entry<Integer, Integer>> for the entries to find the maximal Map.Entry<Integer, Integer> from count.entrySet() (preferable, can be used with Collections.max).
Note: You could use something like MutableInt (Apache commons) or even AtomicInt for mutable map values. I haven't tested the differences but it may be faster.

EDIT : I'm assuming (based on your code) that the goal is to find the number of appearances of the number that appears the most in the array. Calling it "maximum number of duplicates" is misleading.
First of all, the HashSet is useless. You add all the elements to it up front, which means uniqueValues.contains(valueSequence[i]) is always true.
Now, you only want to increment the duplicateCount if you still haven't moved to the next element :
for (int i = 0; i < valueSequence.length; i++)
{
if (i == 0 || valueSequence[i] == valueSequence[i-1])
{
duplicateCount++;
}
else
{
if (duplicateCount > maxCount)
{
maxCount = duplicateCount;
}
duplicateCount = 1; // another small fix
}
}
if (duplicateCount > maxCount)
maxCount = duplicateCount;
}
If the goal is to find the number of duplicates, you can do it without any loop (since the number of duplicates is the total number of elements minus the number of unique elements) :
HashSet<Integer> uniqueValues = new HashSet<Integer>(valueSequenceList);
int duplicateCount = valueSequenceList.size() - uniqueValues.size();

String[] Csssplit = Css.split("====");
HashMap<String,Integer> Spancsslist = new HashMap<String,Integer>();
for(int c=0;c<Csssplit.length;c++){
Css = Csssplit[c];
//System.out.println("css::"+Css);
int count = Spancsslist.getOrDefault(Css, 0);
Spancsslist.put(Css,count+1);
}
if(Spancsslist.size()==0){ continue; }
Spancsslist = Spancsslist.entrySet().stream().sorted(Collections.reverseOrder(Map.Entry.comparingByValue())).collect(toMap(Map.Entry::getKey, Map.Entry::getValue, (e1, e2) -> e2,LinkedHashMap::new));
Css = Spancsslist.keySet().stream().findFirst().get();

using Integer.MIN_VALUE to find max array, then count duplicate max int array.
public static int main(int[] ar) {
int count = 0;
int max = Integer.MIN_VALUE;
int lastMax = 0;
for(int i = 0; i < ar.length; i++) {
if(ar[i] > max) {
max = ar[i];
if(lastMax != max){
count = 0;
}
lastMax = max;
}
if(ar[i] == max) {
count += 1;
}
}
return count;
}

Related

Maximum items to retain after removing k items from array

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;
}

[java]Longest consecutive integers sequence, debug

I have wrote a method for the question:
input: an array of integers
return: the length of longest consecutive integer sequence.
like: for {9,1,2,3}, return 3, cuz{1,2,3}
the method doesnt run well. hope someone could help me with debugging.
public int solution(int[] arr){
int counter = 1;
int max = arr[1];
//find the max in the array
for (int i : arr){
if (i > max){
max = i;
}
}
int[] nArr = new int[max];
for (int i : arr){
nArr[i] = i;
}
List<Integer> counters = new ArrayList<>();
for (int i = 0; i < max; i++){
if (nArr[i] == nArr[i+1] - 1){
counter++;
}else{
counters.add(counter);
counter = 1;
}
}
max = counters.get(1);
for (int i : counters){
if (i > max){
max = i;
}
}
return max; }
thanks a lot!!!
You dont need to use ArrayList... If all you want is max count of sequential integers, then try this:
int[] a = somethingBlaBla;
int counter = 0; // Stores temporary maxes
int secCounter = 0; //Stores final max
for(int j = 0; j<a.length-1; j++){ // Iterate through array
if(a[j] == a[j+1]-1){
counter++; // If match found then increment counter
if(counter > secCounter)
secCounter = counter; // If current match is greater than stored match, replace current match
}
else
counter = 0; // Reset match to accumulate new match
}
System.out.println(secCounter);
As for your method, the first thing I noticed is that max has value of greatest number in array and not the size of array. So if my array is something like {1,2,3,45,6,7,8,9}, it will throw indexOutOfBoundsException because its gonna try get 45th element in array which is not present.

Find the element with highest occurrences in an array [java]

I have to find the element with highest occurrences in a double array.
I did it like this:
int max = 0;
for (int i = 0; i < array.length; i++) {
int count = 0;
for (int j = 0; j < array.length; j++) {
if (array[i]==array[j])
count++;
}
if (count >= max)
max = count;
}
The program works, but it is too slow! I have to find a better solution, can anyone help me?
Update:
As Maxim pointed out, using HashMap would be a more appropriate choice than Hashtable here.
The assumption here is that you are not concerned with concurrency. If synchronized access is needed, use ConcurrentHashMap instead.
You can use a HashMap to count the occurrences of each unique element in your double array, and that would:
Run in linear O(n) time, and
Require O(n) space
Psuedo code would be something like this:
Iterate through all of the elements of your array once: O(n)
For each element visited, check to see if its key already exists in the HashMap: O(1), amortized
If it does not (first time seeing this element), then add it to your HashMap as [key: this element, value: 1]. O(1)
If it does exist, then increment the value corresponding to the key by 1. O(1), amortized
Having finished building your HashMap, iterate through the map and find the key with the highest associated value - and that's the element with the highest occurrence. O(n)
A partial code solution to give you an idea how to use HashMap:
import java.util.HashMap;
...
HashMap hm = new HashMap();
for (int i = 0; i < array.length; i++) {
Double key = new Double(array[i]);
if ( hm.containsKey(key) ) {
value = hm.get(key);
hm.put(key, value + 1);
} else {
hm.put(key, 1);
}
}
I'll leave as an exercise for how to iterate through the HashMap afterwards to find the key with the highest value; but if you get stuck, just add another comment and I'll get you more hints =)
Use Collections.frequency option:
List<String> list = Arrays.asList("1", "1","1","1","1","1","5","5","12","12","12","12","12","12","12","12","12","12","8");
int max = 0;
int curr = 0;
String currKey = null;
Set<String> unique = new HashSet<String>(list);
for (String key : unique) {
curr = Collections.frequency(list, key);
if(max < curr){
max = curr;
currKey = key;
}
}
System.out.println("The number " + currKey + " happens " + max + " times");
Output:
The number 12 happens 10 times
The solution with Java 8
int result = Arrays.stream(array)
.boxed()
.collect(Collectors.groupingBy(i->i,Collectors.counting()))
.values()
.stream()
.max(Comparator.comparingLong(i->i))
.orElseThrow(RuntimeException::new));
I will suggest another method. I don't know if this would work faster or not.
Quick sort the array. Use the built in Arrays.sort() method.
Now compare the adjacent elements.
Consider this example:
1 1 1 1 4 4 4 4 4 4 4 4 4 4 4 4 9 9 9 10 10 10 29 29 29 29 29 29
When the adjacent elements are not equal, you can stop counting that element.
Solution 1: Using HashMap
class test1 {
public static void main(String[] args) {
int[] a = {1,1,2,1,5,6,6,6,8,5,9,7,1};
// max occurences of an array
Map<Integer,Integer> map = new HashMap<>();
int max = 0 ; int chh = 0 ;
for(int i = 0 ; i < a.length;i++) {
int ch = a[i];
map.put(ch, map.getOrDefault(ch, 0) +1);
}//for
Set<Entry<Integer,Integer>> entrySet =map.entrySet();
for(Entry<Integer,Integer> entry : entrySet) {
if(entry.getValue() > max) {max = entry.getValue();chh = entry.getKey();}
}//for
System.out.println("max element => " + chh);
System.out.println("frequency => " + max);
}//amin
}
/*output =>
max element => 1
frequency => 4
*/
Solution 2 : Using count array
public class test2 {
public static void main(String[] args) {
int[] a = {1,1,2,1,5,6,6,6,6,6,8,5,9,7,1};
int max = 0 ; int chh = 0;
int count[] = new int[a.length];
for(int i = 0 ; i <a.length ; i++) {
int ch = a[i];
count[ch] +=1 ;
}//for
for(int i = 0 ; i <a.length ;i++) {
int ch = a[i];
if(count[ch] > max) {max = count[ch] ; chh = ch ;}
}//for
System.out.println(chh);
}//main
}
Here's a java solution --
List<Integer> list = Arrays.asList(1, 2, 2, 3, 2, 1, 3);
Set<Integer> set = new HashSet(list);
int max = 0;
int maxtemp;
int currentNum = 0;
for (Integer k : set) {
maxtemp = Math.max(Collections.frequency(list, k), max);
currentNum = maxtemp != max ? k : currentNum;
max = maxtemp;
}
System.out.println("Number :: " + currentNum + " Occurs :: " + max + " times");
int[] array = new int[] { 1, 2, 4, 1, 3, 4, 2, 2, 1, 5, 2, 3, 5 };
Long max = Arrays.stream(array).boxed().collect(Collectors.groupingBy(i -> i, Collectors.counting())).values()
.stream().max(Comparator.comparing(Function.identity())).orElse(0L);
public static void main(String[] args) {
int n;
int[] arr;
Scanner in = new Scanner(System.in);
System.out.println("Enter Length of Array");
n = in.nextInt();
arr = new int[n];
System.out.println("Enter Elements in array");
for (int i = 0; i < n; i++) {
arr[i] = in.nextInt();
}
int greatest = arr[0];
for (int i = 0; i < arr.length; i++) {
if (arr[i] > greatest) {
greatest = arr[i];
}
}
System.out.println("Greatest Number " + greatest);
int count = 0;
for (int i = 0; i < arr.length; i++) {
if (greatest == arr[i]) {
count++;
}
}
System.out.println("Number of Occurance of " + greatest + ":" + count + " times");
in.close();
}
In continuation to the pseudo-code what you've written try the below written code:-
public static void fetchFrequency(int[] arry) {
Map<Integer, Integer> newMap = new TreeMap<Integer, Integer>(Collections.reverseOrder());
int num = 0;
int count = 0;
for (int i = 0; i < arry.length; i++) {
if (newMap.containsKey(arry[i])) {
count = newMap.get(arry[i]);
newMap.put(arry[i], ++count);
} else {
newMap.put(arry[i], 1);
}
}
Set<Entry<Integer, Integer>> set = newMap.entrySet();
List<Entry<Integer, Integer>> list = new ArrayList<Entry<Integer, Integer>>(set);
Collections.sort(list, new Comparator<Map.Entry<Integer, Integer>>() {
#Override
public int compare(Entry<Integer, Integer> o1, Entry<Integer, Integer> o2) {
return (o2.getValue()).compareTo(o1.getValue());
}
});
for (Map.Entry<Integer, Integer> entry : list) {
System.out.println(entry.getKey() + " ==== " + entry.getValue());
break;
}
//return num;
}
This is how i have implemented in java..
import java.io.*;
class Prog8
{
public static void main(String[] args) throws IOException
{
BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
System.out.println("Input Array Size:");
int size=Integer.parseInt(br.readLine());
int[] arr= new int[size];
System.out.println("Input Elements in Array:");
for(int i=0;i<size;i++)
arr[i]=Integer.parseInt(br.readLine());
int max = 0,pos=0,count = 0;
for (int i = 0; i < arr.length; i++)
{
count=0;
for (int j = 0; j < arr.length; j++)
{
if (arr[i]==arr[j])
count++;
}
if (count >=max)
{
max = count;
pos=i;
}
}
if(max==1)
System.out.println("No Duplicate Element.");
else
System.out.println("Element:"+arr[pos]+" Occourance:"+max);
}
}
Find the element with the highest occurrences in an array using java 8 is given below:
final Long maxOccurrencesElement = arr.stream()
.collect(Collectors.groupingBy(Function.identity(), Collectors.counting()))
.entrySet()
.stream()
.max((o1, o2) -> o1.getValue().compareTo(o2.getValue()))
.get()
.getKey();
You can solve this problem in one loop with without using HashMap or any other data structure in O(1) space complexity.
Initialize two variables count = 0 and max = 0 (or Integer.MIN_VALUE if you have negative numbers in your array)
The idea is you will scan through the array and check the current number,
if it is less than your current max...then do nothing
if it is equal to your max ...then increment the count variable
if it is greater than your max..then update max to current number and set count to 1
Code:
int max = 0, count = 0;
for (int i = 0; i < array.length; i++) {
int num = array[i];
if (num == max) {
count++;
} else if (num > max) {
max = num;
count = 1;
}
}
Here is Ruby SOlution:
def maxOccurence(arr)
m_hash = arr.group_by(&:itself).transform_values(&:count)
elem = 0, elem_count = 0
m_hash.each do |k, v|
if v > elem_count
elem = k
elem_count = v
end
end
"#{elem} occured #{elem_count} times"
end
p maxOccurence(["1", "1","1","1","1","1","5","5","12","12","12","12","12","12","12","12","12","12","8"])
output:
"12 occured 10 times"

Finding modes an an array

Does anyone know how to find the modes in an array when there are more then one mode? I have this code that finds one mode. But I'm dealing with an array which has more than one mode, a multimodal array and I have to print each mode exactly once. Here is my code, can someone help me out? Thanks.
public static int mode(int a[])
{
int maxValue=0, maxCount=0;
for (int i = 0; i < a.length; ++i)
{
int count = 0;
for (int j = 0; j < a.length; ++j)
{
if (a[j] == a[i]) ++count;
}
if (count > maxCount)
{
maxCount = count;
maxValue = a[i];
}
}
return maxCount;
}
public static Integer[] modes(int a[])
{
List<Integer> modes = new ArrayList<Integer>();
int maxCount=0;
for (int i = 0; i < a.length; ++i)
{
int count = 0;
for(int j = 0; j < a.length; ++j)
{
if (a[j] == a[i]) ++count;
}
if (count > maxCount)
{
maxCount = count;
modes.clear();
modes.add(a[i]);
}
else if (count == maxCount)
{
modes.add(a[i]);
}
}
return modes.toArray(new Integer[modes.size()]);
}
Since your elements will be between 10 and 1000, you can use a Counter array. In this Counter array, you can store the counts of the value of the a[i] element. I think you can understand this better in code:
public static List<Integer> mode(int[] a) {
List<Integer> lstMode = new ArrayList<Integer>();
final int MAX_RANGE = 1001;
int[] counterArray = new int[MAX_RANGE]; //can be improved with some maths :)!
//setting the counts for the counter array.
for (int x : a) {
counterArray[x]++;
}
//finding the max value (mode).
int maxCount = counterArray[0];
for(int i = 0; i < MAX_RANGE; i++) {
if (maxCount < counterArray[i]) {
maxCount = counterArray[i];
}
}
//getting all the max values
for(int i = 0; i < MAX_RANGE; i++) {
if (maxCount == counterArray[i]) {
lstMode.add(new Integer(i));
}
}
return lstMode;
}
If your input will have elements outside of 1000, you can look for the Map answer (like in other posts).
We should do this the easy way and utilize a Map data structure in the following format:
Map<Integer,Integer>
And then keep a running total, afterwards you iterate over the keyset and pull the highest value(s) from the Map.
If you want to stay with the List implementation you can do the following to remove dupes:
Set s = new HashSet(list);
list = new ArrayList(s);
One approach is to run (approximately) your current code twice: the first time, find maxCount, and the second time, print out each value that occurs maxCount times. (You'll need to make some modifications in order to print each mode only once, instead of printing it maxCount times.)
Instead of having a single maxValue, store the modes in an ArrayList<Integer>.
if (count == maxCount)
{
modes.add(a[i]);
}
else if (count > maxCount)
{
modes.clear(); // discard all the old modes
modes.add(a[i]);
maxCount = count;
}
and start with j = i instead of j = 0.
Since your array values only range from [10,1000], you could use a Map<Integer,Integer> to store a mapping between each discovered array value (map key) and its count (map value). A HashMap would work very well here.
To increment the count:
int count = (map.contains(a[i]) ? map.get(a[i]) : 1;
map.put(a[i],count);
Continue to track the max count like you already do, and at the end, just iterate over the map and collect all map keys with a map value equal to the max count.

Finding the mode of an array

Ok so I am stuck once again here is what I have
public static int mode(int[][] arr) {
List<Integer> list = new ArrayList<Integer>();
List<Integer> Mode = new ArrayList<Integer>();
for (int i = 0; i < arr.length; i++) {
for (int j = 0; j < arr[i].length; j++) {
list.add(arr[i][j]);
}
}
for(int i = 0; i < list.size(); i ++) {
Mode.add((Mode.indexOf(i)+1));
}
System.out.println(Mode);
return 0;
}
What I am trying to do is in order to find the mathematical mode of this array what I intend to do is for every number I encounter in the array increment the corresponding index by 1 eventually ending up with a new array with "tally" marks in the corresponding indexes, I am not sure } am going about this in the right way I need a dynamic array I assume in order to reach any number that may be encountered so one that can grow to whatever size I need, if my code is complete gibberish feel free to criticize at will :)
Have you considered using a Map instead of a List? That way you can eliminate the ugly indexOf call, and just refer to each instance of the elements by their value, not by doing a linear search each time. Then, all you have to do is find the key with the highest value in your map.
public static Set<Double> getMode(double[] data) {
if (data.length == 0) {
return new TreeSet<>();
}
TreeMap<Double, Integer> map = new TreeMap<>(); //Map Keys are array values and Map Values are how many times each key appears in the array
for (int index = 0; index != data.length; ++index) {
double value = data[index];
if (!map.containsKey(value)) {
map.put(value, 1); //first time, put one
}
else {
map.put(value, map.get(value) + 1); //seen it again increment count
}
}
Set<Double> modes = new TreeSet<>(); //result set of modes, min to max sorted
int maxCount = 1;
Iterator<Integer> modeApperance = map.values().iterator();
while (modeApperance.hasNext()) {
maxCount = Math.max(maxCount, modeApperance.next()); //go through all the value counts
}
for (double key : map.keySet()) {
if (map.get(key) == maxCount) { //if this key's value is max
modes.add(key); //get it
}
}
return modes;
}

Categories

Resources