Find maximum occuring integer (Mode) in an unsorted array - arrays

How to find the integer occurring maximum number of times (mode) in an unsorted array of integers?
One O(nlogn) approach I could think of is to sort. Is there any other better approach?

Here's a basic outline of what you will be doing:
First sort the array - O(n logn) incase of a merge sort
Declare Count=1, Max_Count=1, Max_Value=arr[0]
Iterate through array starting at index 1
Compare each element with Previous element. Update the count, Max_Count if they are equal, else reset count back to 1
return Max_Count, Max_value
Time Complexity : O(n logn)+ O(n)
Space Complexity : InPlace , no hash table or hash map is required.
Here is the code:
public void Max_Occurrence(int[] arr)
{
int count=1;
int max_count =1;
int max_value = arr[0];
for(int i=1; i<arr.length ; i++)
{
if(arr[i-1] == arr[i])
{
count++;
if(max_count<count)
{
max_count = count;
max_value = arr[i];
}
}
else
{
count = 1;//changing from count++. As per the steps mentioned above it should be reset to count = 1. Suggested by an anonymous user
}
}
System.out.println("Result:"+max_value+" has occured "+max_count+"of times");
}

I think you want to find out element that has most occurences in the array -
if you don't care about memory, traverse the array once, increase count of each element in the hashtable. Then find the one with highest count. You'd need one traverse of array and one of the hashtable.
so in pseudocode:
hashtable hash;
foreach(element in array){
if(!hash.contains(element))
hash[element] = 1;
else
hash[element]++;
}
int max = 0;
max_element;
foreach(element in hash)
if(hash[element] > max)
{
max_element = element;
max = hash[element];
}
//max_element contains the maximum occuring one.

If you are using Linq you can do this
IEnumerable.Max();

You can use a hashtable with "the number in array" as key and "occurrences" as values.
Sample code be like this:
hashtable h;
for every entry in array
search hashtable
if present, increment num_occurrences
else, create new entry
Iterate over all the entries in hashtable and return one
with max num_occurrences
As searching in hash is considered O(1), the overall complexity will be O(n).
A special case of this problem is when the numbers in array are in a given range, in that case take another array of ints with size of maximum value in the original array,and use the index of new array as key and the number stored in this array as count of occurrences.
Return the index of the largest value in this array.

Try this.
class max_frequency
{
private int a[]=new int[20];
public void accept(int a1[])
{
a=a1;
}
public void sort()
{
int i,j,t;
for(i=0;i<20;i++)
{
for(j=i+1;j<20;j++)
{
if(a[i]>a[j])
{
t=a[i];
a[i]=a[j];
a[j]=t;
}
}
}
int count=1;
int max_count=1;
int max_value=0;
for(i=1;i<a.length;i++)
{
if(a[i-1]==a[i])
{
count++;
if(max_count<count)
{
max_count=count;
max_value=a[i];
}
}
else
{
count=1;
}
}
System.out.println("Result : "+max_value+ " has occured "+max_count+ " times");
}
}

Related

Consolidating partitions / aka Compaction algorithm

Given number of partitons (usedSpace and its totalSpace) of a hard disk in the form of an list
Example usedSpace = [3,2,1,3,1]
totalSpace = [3,5,3,5,5]
Here usedSpace is the partition getting used out of total space on that partition.
Find the minimum number of partitions need to hold all the data if we move data around partition optimally.
In this cases
a) move data from 1st partion to 2nd partition and 1st partition will be empty
b) move data of 3rd and 5th partition to 4th partition and 3rd and 5th will be free.
Hence only 2 partition needed to hold all the data.
Since the number of moves doesn't matter, and since data can be split up, a greedy approach will work. Pseudocode:
partitionCount := 0
# We're only worried about the total space used vs the total space available
unallocatedDataSize := sum of elements in usedSpace
# Greedily use the largest available space
sort totalSpace by size, descending
while unallocatedDataSize > 0 and totalSpace is not empty
partitionSize := totalSpace.removeFirst()
partitionCount := partitionCount + 1
# Storing partitionSize data in this partition, remove it from our tracking
unallocatedDataSize = unallocatedDataSize - partitionSize
return partitionCount
An optimal and working solution in C#:
public int getMinDrives(int[] used, int[] total)
{
int hdQty = 1;
int pos = 0;
int currentTotal;
Array.Sort(total);
Array.Reverse(total);
int usedSum = used.Sum();
while (usedSum > 0)
{
currentTotal = total[pos];
usedSum = usedSum - currentTotal;
if (usedSum > 0)
{
hdQty++;
pos++;
continue;
}
}
return hdQty;
}
How this can be resolved by Java, if the function returning as Integer value containing args of the amount of used space on each partition and total capacity of each partition, like :
int minPartition(List<Integer> used, List<Integer> totalCapacity), how one can resolve by the above answer supplied by Greedy approach?
The below code responds to Heap space error if i checked with above:
import java.util.ArrayList;
import java.util.List;
public class Program3 {
public static void main(String[] args) {
List<Integer> used = new ArrayList<>();
List<Integer> totalCapacity = new ArrayList<>();
used.add(1);
used.add(2);
used.add(3);
totalCapacity.add(3);
totalCapacity.add(3);
totalCapacity.add(3);
System.out.println(minPartitions(used,totalCapacity));
}
public static int minPartitions(List<Integer> used, List<Integer> totalCapacity) {
// Write your code here
int sizeOfUsedPartion = used.size();
int sizeOfMemoryUsed = totalCapacity.size();
List<Integer> newMemory = new ArrayList<>();
while(sizeOfMemoryUsed != 0)
{
for(int i=0; i<sizeOfUsedPartion;i++)
{
for(int j=0; j<i;j++)
{
if((used.get(i)+used.get(j)) <= totalCapacity.get(i))
{
newMemory.add((used.get(i)+used.get(j)));
break;
}
}
}
}
return newMemory.size();
}
}
//You can use greedy approach. The below code is in c++.
#include<bits/stdc++.h>
using namespace std;
int minParts(vector<int>usedSpace,vector<int>totalSpace){
int q;
q=totalSpace.size();
sort(usedSpace.begin(),usedSpace.end());
sort(totalSpace.begin(),totalSpace.end());
int used=accumulate(usedSpace.begin(),usedSpace.end(),0);
int min=0;
for(int i=q-1;i>=0;i--){
if(used<=totalSpace[i]){
min=min+1;
break;
}
else{
used=used-totalSpace[i];
min=min+1;
}
}
return min;
}
int main(){
vector<int>usedSpace={3,2,1,3,1};
vector<int>totalSpace={3,5,3,5,5};
int m=minParts(usedSpace,totalSpace);
cout<<m;
return 0;
}
//modify the code to give user input
//I could not find a better approach

Storage elements from binary tree in array

I want to store my elements from my binary tree into an array but have no idea how to do it...
I already have a count method for the size of my array, now i need to store my int elements into an array
public int countNode() {
if (this.root == null) {
return 0;
} else {
int count = 1;
count += root.l.countNode();
count += root.r.countNode();
return count;
}
}
public int[] arrayStorage() {
int[] a = new int[countNode()];
}
You can add it to array by level order traversing the tree using queue.
The main reason we don't follow this approach for a binary tree is that this wastes a lot of space in array when the tree isn't complete unlike a heap.

Determine whether or not there exist two elements in an array whose sum is exactly X?

Given an array A[] of N elements and a number x, check for pair in A[] with sum as x ?
Method 1 = Sorting which gives O(n lg n).
Method 2 = Using hash table which gives O(n) .
I am having a doubt in method 2, that what if chaining is used , then for every element we have to search in list for its complement , which can yield O(n^2) in worst case because of chaining .
I think it will work only when range of integers is given , so that we can have hashtable without chaining which gives O(n) . Am i right ?
You can try the following approach ->
hash all elements in A[], like (key, value) = (A[i],true)
for all elements in A[]:
if hash(x-A[i])=true: it exists
You are right about hashtable that O(n) is not the WORST CASE guaranteed complexity.
However, with a reasonable hash function, the worst case should rarely happen.
And of course, if a small enough upper bound is given on the range of numbers, you can just use normal array to do the trick.
O(N) solution which uses hashmap to maintain the element Vs its frequency. Frequency is maintained so as to make it work for duplicate array elements case.
public static boolean countDiffPairsUsingHashing(int[] nums, int target) {
if (nums != null && nums.length > 0) {
HashMap<Integer, Integer> numVsFreq = new HashMap<Integer, Integer>();
for (int i = 0; i < nums.length; i++) {
numVsFreq.put(nums[i], numVsFreq.getOrDefault(nums[i], 0) + 1);
}
for (int i = 0; i < nums.length; i++) {
int diff = target - nums[i];
numVsFreq.put(nums[i], numVsFreq.get(nums[i]) - 1);
if (numVsFreq.get(diff) != null && numVsFreq.get(diff) > 0) {
return true;
}
numVsFreq.put(nums[i], numVsFreq.get(nums[i]) + 1);
}
}
return false;
}

Check if Number Exists in array which first increases then decreases then increases

Given an array first increasing then decreases at a point and again increases?
find a given number N exists in array or not.
Example 1:
Array = 7,8,3,4,5,6
number = 7
answer should be true.
Example 2:
Array = 3,4,6,7,8,5,9,10,11
number = 10
answer should be true.
All numbers are unique.
can be done with linear search in O(N),
Can we do that lesser than that. (more efficient)
In general, no. Suppose we have the following, in Python:
l = range(n)
and we randomly stick a -1 in there:
if random.random() < 0.5:
l[random.randrange(len(l))] = -1
The only way to tell if there's a -1 in the list is to look through every element until you find it or don't. The structure of the list ends up not helping at all.
a linear search is as good as you will get for a non-linear array
Optimized Algorithm : -
Use binary search for key on array if found then return true.
If not found use linear search
Time Complexity : -
Unsuccessful search : Here we would do both linear search and binary search hence O(N) for large inputs
Successful search : Here is where our optimization work to some extent. There is on average 1/2 chance that you end up searching in right part of array in binary search . Hence atleast 2 times faster search on average.
Java Code for optimized algorithm with results :-
public class UniqueSearch {
static int linearCount = 0;
public static boolean binSearch(int[] arr,int key,int high,int low) {
while(high>=low) {
int mid = (low+high)/2;
if(arr[mid]==key)
return(true);
if(arr[mid]<key) {
low = mid+1;
}
else {
high = mid-1;
}
}
return(false);
}
public static boolean linearSearch(int arr[],int key) {
//System.out.println("linearSearch");
linearCount++;
for(int i=0;i<arr.length;i++) {
if(key==arr[i]) {
return(true);
}
}
return(false);
}
public static boolean optSearch2(int arr[],int key) {
boolean flag = binSearch(arr, key, arr.length-1,0);
if(!flag) {
return(linearSearch(arr, key));
}
return(flag);
}
public static void main(String[] args) {
int n = 100000;
int[] arr = new int[n];
int error = 0;
Random r = new Random();
long start = System.currentTimeMillis();
int totalCount = 0;
for(int i=0;i<1000;i++) {
error = r.nextInt(arr.length-1);
for(int k=0;k<error;k++) {
arr[k] = 2*k+1;
}
for(int k=error;k<arr.length;k++) {
arr[k] = 2*(k-error);
}
for(int j=0;j<1000;j++) {
int x = r.nextInt(arr.length);
totalCount++;
boolean flag = optSearch2(arr,arr[x]);
if(!flag) {
System.out.println("error");
}
}
}
System.out.println("linearSearch Percentage: "+linearCount*100/totalCount);
System.out.println(System.currentTimeMillis()-start);
}
}
Results :
Run the code and wait for 6-7 secs and you will see that for random successfull search on random array of the special kind as your problem requires linear search about 30% times and rest can be done using binary search in O(logn)
Can be done in O(logN) time complexity
Find maximum element in array (call this pivot). Here's the pseudo code
public static int getMax(int start, int end){
if(start==end)
return start;
if(start>end)
return -1;
int mid = start + (end-start)/2;
// check if maxima
if(arr[mid-1]<arr[mid] && arr[mid]>arr[mid+1])
return mid;
// check slope
if(arr[mid-1]<arr[mid] && arr[mid]<arr[mid+1]){
//increasing slope
return getMax(mid+1, end);
}
if(arr[mid-1]>arr[mid] && arr[mid]>arr[mid+1]){
return getMax(start, mid-1);
}
return -1;
}
Partition array on pivot element and run two binomial searches for left(increasing) and right(decreasing)
findElem(int key, int pivot){
int index = binSearchInc(start, pivot-1);
if(index>=0)
return index;
else
return binSearchDec(pivot+1, end);
}
Both steps take O(logN) time for execution.

Sudoku in Java. Index out of Bounds Exception

I've got an IndexOutOfBounds exception in the following program. It consists of three files:
Important are only two of them, the GUI is working fine. Here is the first one:
interface SudokuObserver {
public void modified(int i, int j);
}
public class SudokuData
{
public int[][] feld = new int[9][9];
public SudokuObserver obs = null;
public SudokuData()
{
int i,j;
for (i=0; i<9; i++) {
for (j=0; j<9; j++) {
feld[i][j] = 0;
}
}
}
public int getNumber(int x, int y)
{
return feld[x][y];
}
public void setNumber(int x, int y, int v)
{
feld[x][y] = v;
if (obs != null)
obs.modified(x, y);
}
public void setObserver(SudokuObserver o)
{
obs = o;
}
So the Sudoku field is allocated as a 9x9 integer array. The following file is called SudokuSolver and has an algorithm to write the possible numbers for each square into an ArrayList. Then the second algorithm works as following: He finds the square which has the minimum of possible numbers, sets the first of the numbers saved in the ArrayList on that square and does this recursive, so he starts again at defining the possible numbers for each square, taking the one with the smallest number of possibilities and picks the first one to put it into that field. A for-loop runs over the possible Numbers for each square while doing that.
import java.util.*;
public class SudokuSolver
{
SudokuData data;
public SudokuSolver(SudokuData d)
{
data = d;
}
{
/*Pseudoalgorithm:
- Inserts the numbers 1-9 into a Collection called res
- Looks at line x, which numbers are in there and erases them out of the
collection
- Looks at column y, which numbers are in there and erases them out of the
collection
- Looks in the 3x3 Square (x,y) which numbers are already in there and erases
them out of the collection
- Gives back the possible candidates for that field
*/
Here i initialize my ArrayList.
public ArrayList<Integer> offen(int x, int y)
{
ArrayList<Integer> res = new ArrayList<Integer>();
/* The collection is saved in an ArrayList */
int k = 0;
Here I just fill in the numbers 1-9 in my ArrayList.
for (int i=1;i<10;i++)
{
res.add(i);
}
Now comes the difficult part: I loop over j from zero to nine, then over k. The line is constant with the given x, the j runs over the columns, so i got every square in the given line, and in every square i check for every number from 1-9. Care: the index goes from 0-9 while the elements go from 1-9 so k has to be 0-9 cause the get()-method takes an index as input. If there is any compliance I remove the element from the ArrayList.
for (int j=0;j<9;j++)
{
for (k=0;k<9;k++)
{
if (this.data.feld[x][j] == (res.get(k)))
res.remove(k);
}
Same stuff as above for the columns, constant column and j loops.
for (k=0;k<9;k++)
{
if (this.data.feld[j][y] == res.get(k))
res.remove(k);
}
}
Now i get my inputs in two new variables, just because i had typed the code part below before with wrong variable names.
int m = x;
int n = y;
Here is the part for the 3x3 squares, i do this with if conditions, so this is just one of the 9 parts, I didn't want to post them all here, cause they just differ in a few constants. I check in which square my input x,y is, and then I loop over the square and check which numbers are there, which are also still in my ArrayList and remove them.
if (m<=2 && n<=2)
{
for (m=0;m<3;m++)
{
for (n=0;n<3;n++)
{
for (k=0;k<9;k++)
{
if (this.data.feld[m][n] == res.get(k))
res.remove(k);
}
}
}
}
Now I return the ArrayList
return res;
}
//findSolution() finds a Solution
public boolean findSolution()
{
/*Possible Strategy:
- Find the square, which has the fewest possible candidates
- If there are more than one candidates, who have the minimum of candidates,
take any of them
- If there are no more open candidates, there is a solution found. Return
true
- Loop over the candidates of this square and by setting the first possible
candidate into this square[x][y]
- Call the method findSolution() recursive to find in dependence of the set
value the values for the other fields
If there is a blind alley, take the next possible candidate (Backtracking!)
*/
int j = 0;
int k = 0;
int x = 0; // x coordinate of the field with the fewest open candidates
int y = 0; // y coordinate of the field with the fewest open candidates
int counter_offene_felder = 0; // counts the number of open fields
int min = 9;
I'm looping over j and k, looking if the number of possible candidates is more than 0, that means I'm running through the whole sudoku field and count the number of open fields.
for (j=0;j<9;j++)
{
for (k=0;k<9;k++)
{
if ( this.offen(j,k).size() >= 0)
{
counter_offene_felder += 1;
}
If the number is < than min = 9 possible candidates, i take it as the min and save the coordinates of that field
if ( (this.offen(j,k)).size() < min )
{
x = j;
y = k;
}
}
}
now i initialize and ArrayList for the field with the fewest possible candidates and put them into this ArrayList with my offen-method
ArrayList<Integer> candidate_list = this.offen(x,y);
for (k=0;k<this.offen(x,y).size();k++)
{ // runs over candidates
int v = this.offen(x,y).get(k); // takes the first candidate
this.data.setNumber(x,y,v); // writes the first candidate into square [x][y]
this.findSolution(); // calls findSolution() recursive
}
If there are no more open fields, I've found a solution
if (counter_offene_felder == 0)
{
return true;
}
else return false;
}
}
The problem is, that I get an IndexOutOfBounds Exception at line 39, at Index 8 Size 8. But I don't know why. :(
Not positive that this is where you are getting your error... but you could run into an issue when you do something like this.
for (k=0;k<9;k++)
{
if (this.data.feld[j][y] == res.get(k))
res.remove(k);
}
For instance, say that at k=1 the if statement evaluates to true. Then you will remove an element from the ArrayList. Then when k=8, and IndexOutOfBounds exception will be thrown because the ArrayList only contains 8 elements (0-7)
Assuming that no other threads will be modifying this.data.feld[][], you will only ever get one match when going through this loop.. so you could do something like this...
int match = -1;
for (k=0;k<res.size();k++) {
if (this.data.feld[j][y] == res.get(k)){
match = k;
break;
}
}
if(match != -1)
res.remove(match);
I think the contains() method will help eliminate your exceptions for this loop.
Try replacing your code with this:
for (m=0;m<3;m++)
{
for (n=0;n<3;n++)
{
if (res.contains(this.data.field[m][n]))
res.remove(res.indexOf(this.data.field[m][n]));
}
}
It will iterate over the data.field, and check the ArrayList to see if it contains the value at m,n. If it does, it will remove it.

Resources