Can we solve this Sock Merchant problem in less complexity? - java

I have solved the hackerrank Sock Merchant problem But I want to reduce the complexity of the code(I am not sure that it is possible or not).
John works at a clothing store. He has a large pile of socks that he must pair by color for sale. Given an array of integers representing the color of each sock, determine how many pairs of socks with matching colors there are.
For example, there are n=7 socks with colors ar= [1,2,1,2,1,3,2]. There is one pair of color 1 and one of color 2. There are three odd socks left, one of each color. The number of pairs is 2.
Function Description
Complete the sockMerchant function in the editor below. It must return an integer representing the number of matching pairs of socks that are available.
sockMerchant has the following parameter(s):
n: the number of socks in the pile
ar: the colors of each sock
Input Format
The first line contains an integer n, the number of socks represented in ar.
The second line contains n space-separated integers describing the colors ar[i] of the socks in the pile.
Constraints
1 <= n <= 100
1 <= ar[i] <= 100 where 0 <= i < n
Output Format
Return the total number of matching pairs of socks that John can sell.
Sample Input
9
10 20 20 10 10 30 50 10 20
Sample Output
3
My solutions :
package com.hackerrank.test;
public class Solution {
public static void main(String[] args) {
//Initialize array
int[] arr = new int[]{10, 20, 20, 10, 10, 30, 50, 10, 20};
//Array fr will store frequencies of element
System.out.println("---------------------------------------");
System.out.println(" sockMerchant output " + sockMerchant(9, arr));
System.out.println("---------------------------------------");
}
static int sockMerchant(int n, int[] ar) {
int pairs = 0;
int frequencyArray[] = new int[ar.length];
int frequencyTemp = -1;
for (int i = 0; i < ar.length; i++) {
int count = 1;
for (int j = i + 1; j < ar.length; j++) {
if (ar[i] == ar[j]) {
count++;
frequencyArray[j] = frequencyTemp;
}
}
if (frequencyArray[i] != frequencyTemp) {
frequencyArray[i] = count;
}
}
for (int i = 0; i < frequencyArray.length; i++) {
if (frequencyArray[i] != frequencyTemp) {
int divide = frequencyArray[i] / 2;
pairs += divide;
}
}
return pairs;
}
}
And the output is :
---------------------------------------
sockMerchant frequency 3
---------------------------------------

You can solve this in a single pass (O(n)) using a HashSet, which has O(1) put and lookup time. Each element is already in the set, in which case it gets removed and the pair counter is incremented, or it's not, in which case you add it:
int[] arr = new int[]{10, 20, 20, 10, 10, 30, 50, 10, 20};
HashSet<Integer> unmatched = new HashSet<>();
int pairs = 0;
for(int i = 0; i < arr.length; i++) {
if(!unmatched.add(arr[i])) {
unmatched.remove(arr[i]);
pairs++;
}
}

This works for java 8!!
static int sockMerchant(int n, int[] ar) {
Set<Integer> list = new HashSet<Integer>();
int count = 0;
for(int i= 0; i < n; i++){
if(list.contains(ar[i])){
count++;
list.remove(ar[i]);
}
else{
list.add(ar[i]);
}
}
return count;
}

It can also be solved using a dictionary as follows in Swift:
func sockMerchant(n: Int, ar: [Int]) -> Int {
var dictionary: [Int: Int] = [:]
var totalNumberOfPairs: Int = 0
// Store all array elements in a dictionary
// with element as key and occurrence as value
ar.forEach{
dictionary[$0] = (dictionary[$0] ?? 0) + 1
}
// Iterate over the dictionary while checking for occurrence greater or equal 2.
// If found add the integer division of the occurrence to the current total number of pairs
dictionary.forEach { (key, value) in
if value >= 2 {
totalNumberOfPairs = totalNumberOfPairs + (value / 2)
}
}
return totalNumberOfPairs
}

Here my solution with JAVA for Sock Merchant test on HackerRank
import java.io.*;
import java.util.*;
public class sockMerchant {
public static void main(String[] args) {
Scanner en = new Scanner(System.in);
int n=en.nextInt();
int[] hash = new int[300];
for(int i=0; i<n; i++){
hash[en.nextInt()]++;
}
long res=0;
for(int f: hash){
res+=f/2;
}
System.out.println(res);
}
}

Py3 solution for the problem using dictionaries
def sockMerchant(n, ar):
pair = 0
d = {}
for i in ar:
if i in d:
d[i] += 1
if i not in d:
d[i] = 1
print(d)
for x in d:
u = d[x]//2
pair += u
return pair

Code for python 3
n = 9
ar = [10, 20, 20, 10, 10, 30, 50, 10, 20]
def sockMerchant(n, ar):
totalpair = 0
test= list(set(ar))
for i in test:
pair = 0
for j in ar:
if i==j:
pair+=1
if pair>=2:
totalpair=totalpair+int(pair/2)
return totalpair
print(sockMerchant(n,ar))

We can use a Hash Table, for it. As Hash Table's Complexity is O(1)
Look at below code snippet, i created a dictionary in python i.e. Hash Table having key and value. In dictionary, there only exists a unique Key for each value. So, at start dictionary will be empty. We will loop over the provided list and check values in dictionary keys. If that value is not in dictionary key, it means it is unique, add it to the dictionary. if we find value in dictionary key, simply increment pairs counter and remove that key value pair from hash table i.e. dictionary.
def sockMerchant(n, ar):
hash_map = dict()
pairs = 0
for x in range(len(ar)):
if ar[x] in hash_map.keys():
del hash_map[ar[x]]
pairs += 1
else:
hash_map.setdefault(ar[x])
return pairs

This is my simple code for beginners to understand using c++ which prints the count of numbers of pair in the user-defined vector:
#include <bits/stdc++.h>
using namespace std;
vector<string> split_string(string);
// Complete the sockMerchant function below.
int sockMerchant(int n, vector<int> ar) {
int count=0;
vector<int> x;
for(int i=0;i<n;i++){
if(ar[i]!=0)
{
for(int j=i+1;j<n;j++)
{
if(ar[i]==ar[j]){
count++;
ar[j]=0;
break;
}
}}
}
return count;
}
int main()
{
int a,b;
vector<int> v;
cin>>a;
for(int i=0;i<a;i++){
cin>>b;
v.push_back(b);
}
cout<<sockMerchant(a,v);
}

function sockMerchant(n, ar) {
//Need to initiate a count variable to count pairs and return the value
let count = 0
//sort the given array
ar = ar.sort()
//loop through the sorted array
for (let i=0; i < n-1; i++) {
//if the current item equals to the next item
if(ar[i] === ar[i+1]){
//then that's a pair, increment our count variable
count++
//also increment i to skip the next item
i+=1
}
}
//return the count value
return count
}
sockMerchant(9, [10, 20, 20, 10, 10, 30, 50, 10, 20])

For Javascript
function sockMerchant(n, ar) {
// Create an initial variable to hold the pairs
let pairs = 0;
// create an object to temporarily assign pairs
const temp = {};
// loop through the provided array
for (let n of ar) {
// check if current value already exist in your temp object
if (temp[n] in temp) {
// if current value already exist in temp
// delete the value and increase pairs
delete temp[n];
pairs += 1;
} else {
// else add current value to the object
temp[n] = n;
}
}
// return pairs
return pairs;
}

package com.java.example.sock;
import java.io.IOException;
/**
*
* #author Vaquar Khan
*
*/
public class Solution1 {
// Complete the sockMerchant function below.
/*
* John works at a clothing store. He has a large pile of socks that he must pair by color for sale. Given an array of integers representing the color of each sock, determine how many pairs
* of socks with matching colors there are.
* For example, there are socks with colors . There is one pair of color and one of color . There are three odd socks left, one of each color. The number of pairs is .
*/
static int sockMerchant(int n, int[] ar) {
int counter = 0;
int count = 0;
//
for (int i = 0; i < ar.length; i++) {
count = 1;
//
for (int j = i + 1; j < ar.length; j++) {
if (ar[i] == ar[j]) {
count++;
}
}
if (count % 2 == 0) {
counter++;
}
}
return counter;
}
public static void main(String[] args) throws IOException {
int array[] = { 10, 20, 20 ,10 ,10, 30, 50, 10 ,20};
System.out.println(sockMerchant(9, array));
}
}

Refer below one using HashMap and having complexity O(1)
static int sockMerchant(int n, int[] ar) {
int pairs=0;
Map<Integer, Integer> map = new HashMap<>();
for(int i=0;i<n;i++){
if(map.containsKey(ar[i])){
int count=map.get(ar[i]);
map.put(ar[i],++count);
}
else{
map.put(ar[i],1);
}
}
for(int i : map.values()){
pairs=pairs+(i/2);
}
return pairs;
}

static int sockMerchant(int n, int[] ar) {
int pairs = 0;
for (int i = 0; i < ar.length; i++) {
int counter = 0;
for (int j = 0; j < ar.length; j++) {
if (j < i && ar[j] == ar[i]) break;
if(ar[j]==ar[i]) counter++;
}
pairs+=counter/2;
}
return pairs;
}

def sockMerchant(n, ar):
socks = dict()
pairs = 0
for i in ar:
if i in socks:
socks[i] = socks[i]+1
if i not in socks:
socks[i] = 1
if socks[i]%2 == 0:
pairs += 1
return pairs

This problem can be done easily with a hashset. We can take advantage of the HashSet's ability to not store duplicate elements. Here is the code below.
Set<Integer> set = new HashSet<>();
int pairCount = 0;
for(int i = 0; i < arr.length; i++) {
if(set.add(a[i])
set.add(a[i])
else {
pairCount++;
set.remove(a[i]);
}
}
return pairCount;

/*
* Complete the 'sockMerchant' function below.
*
* The function is expected to return an INTEGER.
* The function accepts following parameters:
* 1. INTEGER n
* 2. INTEGER_ARRAY ar
*/
function sockMerchant(n, ar) {
// Write your code here
let count = [];
for (var i = 0; i < ar.length; i++) {
if (count.hasOwnProperty(ar[i])) {
count[ar[i]]++;
}
else {
count[ar[i]] = 1;
}
}
let number = 0;
for (const key in count) {
number += parseInt(count[key] / 2);
}
return number;
}

My answer in C
int sockMerchant(int n, int ar_count, int* ar) {
int matchcounter =0;// each number repeating count
int paircounter=0;//total pair
int size=0;int i,j,k;
bool num_av=false;//number available or not in new array
int numberarray[n];//creating new (same length) array of length n
for(i=0;i<n;i++){
num_av=false;
for(k=0;k<=size;k++){
if(numberarray[k] == ar[i]){
num_av=true;
break;
}
}
if(!num_av){
size+=1;
numberarray[size-1]=ar[i];
for(j=0;j<n;j++){
if(ar[i]==ar[j]){
matchcounter++;
}
}
paircounter += matchcounter/2;
matchcounter=0;
}
}
return paircounter;
}

I wanted to solve this using Array. Here is my solution for Sock Merchant problem on HackerRank (Java 8):
....
import org.apache.commons.lang3.ArrayUtils;
import java.util.Arrays;
class Result {
public static int sockMerchant(int n, List<Integer> ar) {
int[] arr = ar.stream().mapToInt(i->i).toArray();
int counter = 0;
for(int i = 0; i<n; i++) {
if(arr[i]>0) {
int t = arr[i];
arr[i] = -1;
int j = ArrayUtils.indexOf(arr, t);
if(j == -1) {
continue;
} else {
arr[j] = -1;
counter += 1;
}
} else {
continue;
}
}
return counter;
}
}
This has a O(n) time complexity.

Code for Javascript
const set = new Set()
let count = 0;
for(let i = 0; i < i; i++) {
if (set.has(ar[i])) {
count++;
set.delete(ar[i])
} else {
set.add(ar[i])
}
}

You can count the number of times a number appears in the list and divide them by 2
def sockMerchant(n, ar):
unq = set(ar)
count = 0
for i in unq:
count_vals = ar.count(i)
if count_vals>1:
count = count + int(count_vals/2)
return count

The more easiest way I preferred. Answer in Kotlin
var counter = 0
for (i in 0 until n) {
if (arr[i] != 0) {
loop# for (j in i + 1 until n) {
if (arr[i] == arr[j]) {
counter++
arr[j] = 0
break#loop
}
}
}
}
Commenting for better programming

it can also be solved using the built in Set data type as below (my try) -
function sockMerchant(n, ar) {
// Write your code here
let numberSet = [...new Set(ar)];
let pairs = 0;
for(let i=0;i<numberSet.length;i++){
let count = 0;
ar.filter(x => {
if(x == numberSet[i])
count++;
});
pairs+= count / 2 >= 1 ? Math.trunc(count / 2) : 0;
}
return pairs;
}

Using Python 3:
def sockMerchant(n, ar):
flag = 0
for i in range(n):
if ar[i:].count(ar[i])%2==0:
flag+=1
return flag

Think how you would do it in real life. If someone handed you these socks one-by-one, you'd like think, "Do I have one of these already?" If not, you'd set it down and move on to check on the next sock. When you find one you've already set down, you'd move the pair to the side and count that as another found pair.
Programmatically you may take advantage of a HashSet given it's quick access (constant) and that it only allows for one entry per unique key. Therefore, you can attempt add to the set. Failure to do so means it already exists, count and remove the pair, and continue.
Time-complexity: O(n) [n = number of socks]
Space-complexity: O(m) [m = number of UNIQUE sock types]
Java 8:
public static int sockMerchant(int n, List<Integer> ar)
{
Set<Integer> uniqueSockFound = new HashSet<Integer>();
int countedPairs = 0;
//Iterate through each sock checking if a match has been found already or not
for(Integer sock: ar)
{
//If adding the sock to the set is a success, it doesn't exist yet
//Otherwise, a pair exists, so remove the item and increment the count of pairs
if(!uniqueSockFound.add(sock))
{
countedPairs++;
uniqueSockFound.remove(sock);
}
}
//Return count of pairs
return countedPairs;
}

Here is my solution and it worked for the given set of inputs.
import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int size = sc.nextInt();
int[] arr = new int[size];
for (int i = 0 ; i < size ; i++) {
arr[i] = sc.nextInt();
}
int flag = 0;
for (int j = 0; j < size; j++) {
int count = 0;
for(int i = j + 1; i < size ; i++) {
if (arr[j] == arr[i]) {
count++;
}
}
flag += count / 2;
}
System.out.println(flag);
}
}

I solve it with golang
func sockMerchant(n int32, ar []int32) int32 {
// Write your code here
var indexPairs []int;
var count int32;
var operation bool;
for i := 0; i< len(ar)-1; i++{
for j := i+1; j< len(ar); j++{
//check indexPairs
operation = true;
for k := 0; k< len(indexPairs); k++{
if indexPairs[k] == i || indexPairs[k]==j{
operation = false;
}
}
if operation {
if(ar[i]==ar[j]){
count ++;
indexPairs = append(indexPairs, i, j)
}
}
}
}
return count;
}```

using PYTHON language
from itertools import groupby
def sockmerchant(n,ar):
c=0
a=[]
ar.sort()
for k,g in groupby(ar): # in this same elements group into one list
a.append(len(list(g)))
for i in a:
c=c+(i//2)
return c
n=int(input())
ar=list(map(int,input().split(' ')))
print(sockMerchant(n,ar))

function sockMerchant(n, ar){
let res = 0;
let arr= {};
for (let element of ar){
arr[element] = arr[element]+1 || 1
if(arr[element]%2 == 0){
res++;
}
}
return res;
}
sockMerchant(4,[10,10,20,20]);

public static int sockMerchant(int n, List<Integer> ar) {
int pair = 0;
List<Integer> matchedIndices = new ArrayList<>();
for (int i = 0; i < n; i++) {
if (matchedIndices.contains(i)) {
continue;
}
for (int j = 0; j < n; j++) {
if (j == i || matchedIndices.contains(j)) {
continue;
}
if (ar.get(i) == ar.get(j)) {
pair++;
matchedIndices.add(i);
matchedIndices.add(j);
break;
}
}
}
return pair;
}

I will give an example of solving this problem in C++ using unordered_map. It's overkill, to be honest, and it's done with unordered_set as well (removing the element as a replacement for a boolean in the map). But this more clearly shows the coding path to first do everything right, and only after that take an optimization step and convert to unordered_set.
using namespace std;
/*
* Complete the 'sockMerchant' function below.
*
* The function is expected to return an INTEGER.
* The function accepts following parameters:
* 1. INTEGER n
* 2. INTEGER_ARRAY ar
*/
int sockMerchant(int n, vector<int> ar) {
if (n<1 && n>100 ) return 0;
unordered_map<int, bool> scExtract;
int result=0;
// false --first sock finded
// true --second sock funded
for (auto sCol:ar) {
if (sCol<1 && sCol>100 ) return 0;
if (scExtract.find(sCol) != scExtract.end()) {
if ( scExtract[sCol]) {
scExtract[sCol]=false;
} else {
scExtract[sCol]=true;
result++;
}
} else {
scExtract.insert(pair<int, bool>(sCol, false));
}
}
return result;
}

Related

Find the max value of the same length nails after hammered

I'm trying to solve this problem:
Given an array of positive integers, and an integer Y, you are allowed to replace at most Y array-elements with lesser values. Your goal is for the array to end up with as large a subset of identical values as possible. Return the size of this largest subset.
The array is originally sorted in increasing order, but you do not need to preserve that property.
So, for example, if the array is [10,20,20,30,30,30,40,40,40] and Y = 3, the result should be 6, because you can get six 30s by replacing the three 40s with 30s. If the array is [20,20,20,40,50,50,50,50] and Y = 2, the result should be 5, because you can get five 20s by replacing two of the 50s with 20s.
Below is my solution with O(nlogn) time complexity. (is that right?) I wonder if I can further optimize this solution?
Thanks in advance.
public class Nails {
public static int Solutions(int[] A, int Y) {
int N = A.length;
TreeMap < Integer, Integer > nailMap = new TreeMap < Integer, Integer > (Collections.reverseOrder());
for (int i = 0; i < N; i++) {
if (!nailMap.containsKey(A[i])) {
nailMap.put(A[i], 1);
} else {
nailMap.put(A[i], nailMap.get(A[i]) + 1);
}
}
List < Integer > nums = nailMap.values().stream().collect(Collectors.toList());
if (nums.size() == 1) {
return nums.get(0);
}
//else
int max = nums.get(0);
int longer = 0;
for (int j = 0; j < nums.size(); j++) {
int count = 0;
if (Y < longer) {
count = Y + nums.get(j);
} else {
count = longer + nums.get(j);
}
if (max < count) {
max = count;
}
longer += nums.get(j);
}
return max;
}
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
while (scanner.hasNext()) {
String[] input = scanner.nextLine().replaceAll("\\[|\\]", "").split(",");
System.out.println(Arrays.toString(input));
int[] A = new int[input.length - 1];
int Y = Integer.parseInt(input[input.length - 1]);
for (int i = 0; i < input.length; i++) {
if (i < input.length - 1) {
A[i] = Integer.parseInt(input[i]);
} else {
break;
}
}
int result = Solutions(A, Y);
System.out.println(result);
}
}
}
A C++ implementation would like the following where A is the sorted pin size array and K is the number of times the pins can be hammered.
{1,1,3,3,4,4,4,5,5}, K=2 should give 5 as the answer
{1,1,3,3,4,4,4,5,5,6,6,6,6,6,6}, K=2 should give 6 as the answer
int maxCount(vector<int>& A, int K) {
int n = A.size();
int best = 0;
int count = 1;
for (int i = 0; i < n-K-1; i++) {
if (A[i] == A[i + 1])
count = count + 1;
else
count = 1;
if (count > best)
best = count;
}
int result = max(best+K, min(K+1, n));
return result;
}
Since the array is sorted to begin with, a reasonably straightforward O(n) solution is, for each distinct value, to count how many elements have that value (by iteration) and how many elements have a greater value (by subtraction).
public static int doIt(final int[] array, final int y) {
int best = 0;
int start = 0;
while (start < array.length) {
int end = start;
while (end < array.length && array[end] == array[start]) {
++end;
}
// array[start .. (end-1)] is now the subarray consisting of a
// single value repeated (end-start) times.
best = Math.max(best, end - start + Math.min(y, array.length - end));
start = end; // skip to the next distinct value
}
assert best >= Math.min(y + 1, array.length); // sanity-check
return best;
}
First, iterate through all the nails and create a hash H that stores the number of nails for each size. For [1,2,2,3,3,3,4,4,4], H should be:
size count
1 : 1
2 : 2
3 : 3
4 : 3
Now create an little algorithm to evaluate the maximum sum for each size S, given Y:
BestForSize(S, Y){
total = H[S]
while(Y > 0){
S++
if(Y >= H[S] and S < biggestNailSize){
total += H[S]
Y -= H[S]
}
else{
total += Y
Y = 0
}
}
return total;
}
Your answer should be max(BestForSize(0, Y), BestForSize(1, Y), ..., BestForSize(maxSizeOfNail, Y)).
The complexity is O(n²). A tip to optimize is to start from the end. For example, after you have the maximum value of nails in the size 4, how can you use your answer to find the maximum number of size 3?
Here is my java implementation: First I build a reversed map of each integer and its occurence for example {1,1,1,1,3,3,4,4,5,5} would give {5=2, 4=2, 3=2, 1=4}, then for each integer I calculate the max occurence that we can get of it regarding the K and the occurences of the highest integers in the array.
public static int ourFunction(final int[] A, final int K) {
int length = A.length;
int a = 0;
int result = 0;
int b = 0;
int previousValue = 0;
TreeMap < Integer, Integer > ourMap = new TreeMap < Integer, Integer > (Collections.reverseOrder());
for (int i = 0; i < length; i++) {
if (!ourMap.containsKey(A[i])) {
ourMap.put(A[i], 1);
} else {
ourMap.put(A[i], ourMap.get(A[i]) + 1);
}
}
for (Map.Entry<Integer, Integer> entry : ourMap.entrySet()) {
if( a == 0) {
a++;
result = entry.getValue();
previousValue = entry.getValue();
} else {
if( K < previousValue)
b = K;
else
b = previousValue;
if ( b + entry.getValue() > result )
result = b + entry.getValue();
previousValue += entry.getValue();
}
}
return result;
}
Since the array is sorted, we can have an O(n) solution by iterating and checking if current element is equals to previous element and keeping track of the max length.
static int findMax(int []a,int y) {
int n = a.length,current = 1,max = 0,diff = 0;
for(int i = 1; i< n; i++) {
if(a[i] == a[i-1]) {
current++;
diff = Math.min(y, n-i-1);
max = Math.max(max, current+diff);
}else {
current = 1;
}
}
return max;
}
given int array is not sorted than you should sort
public static int findMax(int []A,int K) {
int current = 1,max = 0,diff = 0;
List<Integer> sorted=Arrays.stream(A).sorted().boxed().collect(Collectors.toList());
for(int i = 1; i< sorted.size(); i++) {
if(sorted.get(i).equals(sorted.get(i-1))) {
current++;
diff = Math.min(K, sorted.size()-i-1);
max = Math.max(max, current+diff);
}else {
current = 1;
}
}
return max;
}
public static void main(String args[]) {
List<Integer> A = Arrays.asList(3,1,5,3,4,4,3,3,5,5,5,1);
int[] Al = A.stream().mapToInt(Integer::intValue).toArray();
int result=findMax(Al, 5);
System.out.println(result);
}

How can I find the mode of a number in an array? [duplicate]

int[] a = new int[10]{1,2,3,4,5,6,7,7,7,7};
how can I write a method and return 7?
I want to keep it native without the help of lists, maps or other helpers.
Only arrays[].
Try this answer. First, the data:
int[] a = {1,2,3,4,5,6,7,7,7,7};
Here, we build a map counting the number of times each number appears:
Map<Integer, Integer> map = new HashMap<Integer, Integer>();
for (int i : a) {
Integer count = map.get(i);
map.put(i, count != null ? count+1 : 1);
}
Now, we find the number with the maximum frequency and return it:
Integer popular = Collections.max(map.entrySet(),
new Comparator<Map.Entry<Integer, Integer>>() {
#Override
public int compare(Entry<Integer, Integer> o1, Entry<Integer, Integer> o2) {
return o1.getValue().compareTo(o2.getValue());
}
}).getKey();
As you can see, the most popular number is seven:
System.out.println(popular);
> 7
EDIT
Here's my answer without using maps, lists, etc. and using only arrays; although I'm sorting the array in-place. It's O(n log n) complexity, better than the O(n^2) accepted solution.
public int findPopular(int[] a) {
if (a == null || a.length == 0)
return 0;
Arrays.sort(a);
int previous = a[0];
int popular = a[0];
int count = 1;
int maxCount = 1;
for (int i = 1; i < a.length; i++) {
if (a[i] == previous)
count++;
else {
if (count > maxCount) {
popular = a[i-1];
maxCount = count;
}
previous = a[i];
count = 1;
}
}
return count > maxCount ? a[a.length-1] : popular;
}
public int getPopularElement(int[] a)
{
int count = 1, tempCount;
int popular = a[0];
int temp = 0;
for (int i = 0; i < (a.length - 1); i++)
{
temp = a[i];
tempCount = 0;
for (int j = 1; j < a.length; j++)
{
if (temp == a[j])
tempCount++;
}
if (tempCount > count)
{
popular = temp;
count = tempCount;
}
}
return popular;
}
Take a map to map element - > count
Iterate through array and process the map
Iterate through map and find out the popular
Assuming your array is sorted (like the one you posted) you could simply iterate over the array and count the longest segment of elements, it's something like #narek.gevorgyan's post but without the awfully big array, and it uses the same amount of memory regardless of the array's size:
private static int getMostPopularElement(int[] a){
int counter = 0, curr, maxvalue, maxcounter = -1;
maxvalue = curr = a[0];
for (int e : a){
if (curr == e){
counter++;
} else {
if (counter > maxcounter){
maxcounter = counter;
maxvalue = curr;
}
counter = 0;
curr = e;
}
}
if (counter > maxcounter){
maxvalue = curr;
}
return maxvalue;
}
public static void main(String[] args) {
System.out.println(getMostPopularElement(new int[]{1,2,3,4,5,6,7,7,7,7}));
}
If the array is not sorted, sort it with Arrays.sort(a);
Using Java 8 Streams
int data[] = { 1, 5, 7, 4, 6, 2, 0, 1, 3, 2, 2 };
Map<Integer, Long> count = Arrays.stream(data)
.boxed()
.collect(Collectors.groupingBy(Function.identity(), counting()));
int max = count.entrySet().stream()
.max((first, second) -> {
return (int) (first.getValue() - second.getValue());
})
.get().getKey();
System.out.println(max);
Explanation
We convert the int[] data array to boxed Integer Stream. Then we collect by groupingBy on the element and use a secondary counting collector for counting after the groupBy.
Finally we sort the map of element -> count based on count again by using a stream and lambda comparator.
This one without maps:
public class Main {
public static void main(String[] args) {
int[] a = new int[]{ 1, 2, 3, 4, 5, 6, 7, 7, 7, 7 };
System.out.println(getMostPopularElement(a));
}
private static int getMostPopularElement(int[] a) {
int maxElementIndex = getArrayMaximumElementIndex(a);
int[] b = new int[a[maxElementIndex] + 1]
for (int i = 0; i < a.length; i++) {
++b[a[i]];
}
return getArrayMaximumElementIndex(b);
}
private static int getArrayMaximumElementIndex(int[] a) {
int maxElementIndex = 0;
for (int i = 1; i < a.length; i++) {
if (a[i] >= a[maxElementIndex]) {
maxElementIndex = i;
}
}
return maxElementIndex;
}
}
You only have to change some code if your array can have elements which are < 0.
And this algorithm is useful when your array items are not big numbers.
If you don't want to use a map, then just follow these steps:
Sort the array (using Arrays.sort())
Use a variable to hold the most popular element (mostPopular), a variable to hold its number of occurrences in the array (mostPopularCount), and a variable to hold the number of occurrences of the current number in the iteration (currentCount)
Iterate through the array. If the current element is the same as mostPopular, increment currentCount. If not, reset currentCount to 1. If currentCount is > mostPopularCount, set mostPopularCount to currentCount, and mostPopular to the current element.
Seems like you are looking for the Mode value (Statistical Mode) , have a look at Apache's Docs for Statistical functions.
package frequent;
import java.util.HashMap;
import java.util.Map;
public class Frequent_number {
//Find the most frequent integer in an array
public static void main(String[] args) {
int arr[]= {1,2,3,4,3,2,2,3,3};
System.out.println(getFrequent(arr));
System.out.println(getFrequentBySorting(arr));
}
//Using Map , TC: O(n) SC: O(n)
static public int getFrequent(int arr[]){
int ans=0;
Map<Integer,Integer> m = new HashMap<>();
for(int i:arr){
if(m.containsKey(i)){
m.put(i, m.get(i)+1);
}else{
m.put(i, 1);
}
}
int maxVal=0;
for(Integer in: m.keySet()){
if(m.get(in)>maxVal){
ans=in;
maxVal = m.get(in);
}
}
return ans;
}
//Sort the array and then find it TC: O(nlogn) SC: O(1)
public static int getFrequentBySorting(int arr[]){
int current=arr[0];
int ansCount=0;
int tempCount=0;
int ans=current;
for(int i:arr){
if(i==current){
tempCount++;
}
if(tempCount>ansCount){
ansCount=tempCount;
ans=i;
}
current=i;
}
return ans;
}
}
Array elements value should be less than the array length for this one:
public void findCounts(int[] arr, int n) {
int i = 0;
while (i < n) {
if (arr[i] <= 0) {
i++;
continue;
}
int elementIndex = arr[i] - 1;
if (arr[elementIndex] > 0) {
arr[i] = arr[elementIndex];
arr[elementIndex] = -1;
}
else {
arr[elementIndex]--;
arr[i] = 0;
i++;
}
}
Console.WriteLine("Below are counts of all elements");
for (int j = 0; j < n; j++) {
Console.WriteLine(j + 1 + "->" + Math.Abs(arr[j]));
}
}
Time complexity of this will be O(N) and space complexity will be O(1).
import java.util.Scanner;
public class Mostrepeatednumber
{
public static void main(String args[])
{
int most = 0;
int temp=0;
int count=0,tempcount;
Scanner in=new Scanner(System.in);
System.out.println("Enter any number");
int n=in.nextInt();
int arr[]=new int[n];
System.out.print("Enter array value:");
for(int i=0;i<=n-1;i++)
{
int n1=in.nextInt();
arr[i]=n1;
}
//!!!!!!!! user input concept closed
//logic can be started
for(int j=0;j<=n-1;j++)
{
temp=arr[j];
tempcount=0;
for(int k=1;k<=n-1;k++)
{
if(temp==arr[k])
{
tempcount++;
}
if(count<tempcount)
{
most=arr[k];
count=tempcount;
}
}
}
System.out.println(most);
}
}
Best approach will be using map where key will be element and value will be the count of each element. Along with that keep an array of size that will contain the index of most popular element . Populate this array while map construction itself so that we don't have to iterate through map again.
Approach 2:-
If someone want to go with two loop, here is the improvisation from accepted answer where we don't have to start second loop from one every time
public class TestPopularElements {
public static int getPopularElement(int[] a) {
int count = 1, tempCount;
int popular = a[0];
int temp = 0;
for (int i = 0; i < (a.length - 1); i++) {
temp = a[i];
tempCount = 0;
for (int j = i+1; j < a.length; j++) {
if (temp == a[j])
tempCount++;
}
if (tempCount > count) {
popular = temp;
count = tempCount;
}
}
return popular;
}
public static void main(String[] args) {
int a[] = new int[] {1,2,3,4,5,6,2,7,7,7};
System.out.println("count is " +getPopularElement(a));
}
}
Assuming your int array is sorted, i would do...
int count = 0, occur = 0, high = 0, a;
for (a = 1; a < n.length; a++) {
if (n[a - 1] == n[a]) {
count++;
if (count > occur) {
occur = count;
high = n[a];
}
} else {
count = 0;
}
}
System.out.println("highest occurence = " + high);
public static int getMostCommonElement(int[] array) {
Arrays.sort(array);
int frequency = 1;
int biggestFrequency = 1;
int mostCommonElement = 0;
for(int i=0; i<array.length-1; i++) {
frequency = (array[i]==array[i+1]) ? frequency+1 : 1;
if(frequency>biggestFrequency) {
biggestFrequency = frequency;
mostCommonElement = array[i];
}
}
return mostCommonElement;
}
Mine Linear O(N)
Using map to save all the differents elements found in the array and saving the number of times ocurred, then just getting the max from the map.
import java.util.HashMap;
import java.util.Map;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Map;
import java.util.stream.IntStream;
public class MosftOftenNumber {
// for O(N) + map O(1) = O(N)
public static int mostOftenNumber(int[] a)
{
final Map m = new HashMap<Integer,Integer>();
int max = 0;
int element = 0;
for (int i=0; i<a.length; i++){
//initializing value for the map the value will have the counter of each element
//first time one new number its found will be initialize with zero
if (m.get(a[i]) == null)
m.put(a[i],0);
//save each value from the array and increment the count each time its found
m.put(a[i] , (Integer) m.get(a[i]) + 1);
//check the value from each element and comparing with max
if ( (Integer) m.get(a[i]) > max){
max = (Integer) m.get(a[i]);
element = a[i];
}
}
System.out.println("Times repeated: " + max);
return element;
}
public static int mostOftenNumberWithLambdas(int[] a)
{
Integer max = IntStream.of(a).boxed().max(Integer::compareTo).get();
Integer coumtMax = Math.toIntExact(IntStream.of(a).boxed().filter(number -> number.equals(max)).count());
System.out.println("Times repeated: " + coumtMax);
return max;
}
public static void main(String args[]) {
// int[] array = {1,1,2,1,1};
// int[] array = {2,2,1,2,2};
int[] array = {1,2,3,4,5,6,7,7,7,7};
System.out.println("Most often number with loops: " + mostOftenNumber(array));
System.out.println("Most often number with lambdas: " + mostOftenNumberWithLambdas(array));
}
}
Solution 1: Hashmap: O(n)
def most_freq_elem(arr):
frequency = {}
most_frequent, most_count = -1, 0
for num in arr:
frequency[num] = frequency.get(num, 0) + 1
if frequency[num] > most_count:
most_count = frequency[num]
most_frequent = num
return most_frequent
Solution 2: Hashmap + Max: O(n)
def most_freq_elem(arr):
frequency = {}
for num in arr:
frequency[num] = frequency.get(num, 0) + 1
return max(frequency, key=frequency.get)
public static void main(String[] args) {
int[] myArray = {1,5,4,4,22,4,9,4,4,8};
Map<Integer,Integer> arrayCounts = new HashMap<>();
Integer popularCount = 0;
Integer popularValue = 0;
for(int i = 0; i < myArray.length; i++) {
Integer count = arrayCounts.get(myArray[i]);
if (count == null) {
count = 0;
}
arrayCounts.put(myArray[i], count == 0 ? 1 : ++count);
if (count > popularCount) {
popularCount = count;
popularValue = myArray[i];
}
}
System.out.println(popularValue + " --> " + popularCount);
}
below code can be put inside a main method
// TODO Auto-generated method stub
Integer[] a = { 11, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, 4, 1, 2, 2, 2, 2, 3, 4, 2 };
List<Integer> list = new ArrayList<Integer>(Arrays.asList(a));
Set<Integer> set = new HashSet<Integer>(list);
int highestSeq = 0;
int seq = 0;
for (int i : set) {
int tempCount = 0;
for (int l : list) {
if (i == l) {
tempCount = tempCount + 1;
}
if (tempCount > highestSeq) {
highestSeq = tempCount;
seq = i;
}
}
}
System.out.println("highest sequence is " + seq + " repeated for " + highestSeq);
public class MostFrequentIntegerInAnArray {
public static void main(String[] args) {
int[] items = new int[]{2,1,43,1,6,73,5,4,65,1,3,6,1,1};
System.out.println("Most common item = "+getMostFrequentInt(items));
}
//Time Complexity = O(N)
//Space Complexity = O(N)
public static int getMostFrequentInt(int[] items){
Map<Integer, Integer> itemsMap = new HashMap<Integer, Integer>(items.length);
for(int item : items){
if(!itemsMap.containsKey(item))
itemsMap.put(item, 1);
else
itemsMap.put(item, itemsMap.get(item)+1);
}
int maxCount = Integer.MIN_VALUE;
for(Entry<Integer, Integer> entry : itemsMap.entrySet()){
if(entry.getValue() > maxCount)
maxCount = entry.getValue();
}
return maxCount;
}
}
int largest = 0;
int k = 0;
for (int i = 0; i < n; i++) {
int count = 1;
for (int j = i + 1; j < n; j++) {
if (a[i] == a[j]) {
count++;
}
}
if (count > largest) {
k = a[i];
largest = count;
}
}
So here n is the length of the array, and a[] is your array.
First, take the first element and check how many times it is repeated and increase the counter (count) as to see how many times it occurs.
Check if this maximum number of times that a number has so far occurred if yes, then change the largest variable (to store the maximum number of repetitions) and if you would like to store the variable as well, you can do so in another variable (here k).
I know this isn't the fastest, but definitely, the easiest way to understand
import java.util.HashMap;
import java.util.Map;
import java.lang.Integer;
import java.util.Iterator;
public class FindMood {
public static void main(String [] args){
int arrayToCheckFrom [] = {1,2,4,4,5,5,5,3,3,3,3,3,3,3,3};
Map map = new HashMap<Integer, Integer>();
for(int i = 0 ; i < arrayToCheckFrom.length; i++){
int sum = 0;
for(int k = 0 ; k < arrayToCheckFrom.length ; k++){
if(arrayToCheckFrom[i]==arrayToCheckFrom[k])
sum += 1;
}
map.put(arrayToCheckFrom[i], sum);
}
System.out.println(getMaxValue(map));
}
public static Integer getMaxValue( Map<Integer,Integer> map){
Map.Entry<Integer,Integer> maxEntry = null;
Iterator iterator = map.entrySet().iterator();
while(iterator.hasNext()){
Map.Entry<Integer,Integer> pair = (Map.Entry<Integer,Integer>) iterator.next();
if(maxEntry == null || pair.getValue().compareTo(maxEntry.getValue())>0){
maxEntry = pair;
}
}
return maxEntry.getKey();
}
}
Comparing two arrays, I Hope for that this is useful for you.
public static void main(String []args){
int primerArray [] = {1,2,1,3,5};
int arrayTow [] = {1,6,7,8};
int numberMostRepetly = validateArrays(primerArray,arrayTow);
System.out.println(numberMostRepetly);
}
public static int validateArrays(int primerArray[], int arrayTow[]){
int numVeces = 0;
for(int i = 0; i< primerArray.length; i++){
for(int c = i+1; c < primerArray.length; c++){
if(primerArray[i] == primerArray[c]){
numVeces = primerArray[c];
// System.out.println("Numero que mas se repite");
//System.out.println(numVeces);
}
}
for(int a = 0; a < arrayTow.length; a++){
if(numVeces == arrayTow[a]){
// System.out.println(numVeces);
return numVeces;
}
}
}
return 0;
}
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.Map.Entry;
public class MostOccuringEleementInArrayOfIntegers {
public static void main(String[] args) {
int[] arr = { 1, 2, 3, 4, 4, 5, 3, 2, 1, 6, 7, 1, 2, 3, 2 };
Map<Integer, Integer> map = new HashMap<Integer, Integer>();
for (int num : arr) {
if (map.containsKey(num)) {
map.put(num, map.get(num) + 1);
} else {
map.put(num, 1);
}
}
Set<Entry<Integer, Integer>> entrySet = map.entrySet();
int max = 1;
int mostFrequent = 1;
for (Entry<Integer, Integer> e : map.entrySet()) {
// Swapping of the elements who is occuring most
if (e.getValue() > max) {
mostFrequent = e.getKey();
max = e.getValue();
}
}
// Print most frequent element
System.out.println("Most frequent element: " + mostFrequent);
}
}
public class MostFrequentNumber {
public MostFrequentNumber() {
}
int frequentNumber(List<Integer> list){
int popular = 0;
int holder = 0;
for(Integer number: list) {
int freq = Collections.frequency(list,number);
if(holder < freq){
holder = freq;
popular = number;
}
}
return popular;
}
public static void main(String[] args){
int[] numbers = {4,6,2,5,4,7,6,4,7,7,7};
List<Integer> list = new ArrayList<Integer>();
for(Integer num : numbers){
list.add(num);
}
MostFrequentNumber mostFrequentNumber = new MostFrequentNumber();
System.out.println(mostFrequentNumber.frequentNumber(list));
}
}
You can count the occurrences of the different numbers, then look for the highest one. This is an example that uses a Map, but could relatively easily be adapted to native arrays.
Second largest element:
Let us take example : [1,5,4,2,3] in this case,
Second largest element will be 4.
Sort the Array in descending order, once the sort done output will be
A = [5,4,3,2,1]
Get the Second Largest Element from the sorted array Using Index 1. A[1] -> Which will give the Second largest element 4.
private static int getMostOccuringElement(int[] A) {
Map occuringMap = new HashMap();
//count occurences
for (int i = 0; i < A.length; i++) {
if (occuringMap.get(A[i]) != null) {
int val = occuringMap.get(A[i]) + 1;
occuringMap.put(A[i], val);
} else {
occuringMap.put(A[i], 1);
}
}
//find maximum occurence
int max = Integer.MIN_VALUE;
int element = -1;
for (Map.Entry<Integer, Integer> entry : occuringMap.entrySet()) {
if (entry.getValue() > max) {
max = entry.getValue();
element = entry.getKey();
}
}
return element;
}
I hope this helps.
public class Ideone {
public static void main(String[] args) throws java.lang.Exception {
int[] a = {1,2,3,4,5,6,7,7,7};
int len = a.length;
System.out.println(len);
for (int i = 0; i <= len - 1; i++) {
while (a[i] == a[i + 1]) {
System.out.println(a[i]);
break;
}
}
}
}
This is the wrong syntax. When you create an anonymous array you MUST NOT give its size.
When you write the following code :
new int[] {1,23,4,4,5,5,5};
You are here creating an anonymous int array whose size will be determined by the number of values that you provide in the curly braces.
You can assign this a reference as you have done, but this will be the correct syntax for the same :-
int[] a = new int[]{1,2,3,4,5,6,7,7,7,7};
Now, just Sysout with proper index position:
System.out.println(a[7]);

Returning the index of the n-th highest value of an unsorted list

I have written the following code and am now trying to figure out the best way to achieve what is explained in the four comments:
Integer[] expectedValues = new Integer[4];
for (int i = 0; i <= 3; i++) {
expectedValues[i] = getExpectedValue(i);
}
int choice = randomNumGenerator.nextInt(100) + 1;
if (choice <= intelligence) {
// return index of highest value in expectedValues
} else if (choice <= intelligence * 2) {
// return index of 2nd highest value in expectedValues
} else if (choice <= intelligence * 3) {
// return index of 3rd highest value in expectedValues
} else {
// return index of lowest value in expectedValues
}
What would be an elegant way o doing so? I do not need to keep expected values as an array - I am happy to use any data structure.
You could create a new array containing the indices and sort on the values - in semi-pseudo code it could look like this (to be adapted):
int[][] valueAndIndex = new int[n][2];
//fill array:
valueAndIndex[i][0] = i;
valueAndIndex[i][1] = expectedValues[i];
//sort on values in descending order
Arrays.sort(valueAndIndex, (a, b) -> Integer.compare(b[1], a[1]));
//find n-th index
int n = 3; //3rd largest number
int index = valueAndIndex[n - 1][0];
If you want to work with simple arrays, maybe this might be a solution:
public static void main(String[] args) {
int[] arr = new int[] { 1, 4, 2, 3 };
int[] sorted = sortedCopy(arr);
int choice = randomNumGenerator.nextInt(100) + 1;
if (choice <= intelligence) {
System.out.println(findIndex(arr, sorted[3])); // 1
} else if (choice <= intelligence * 2) {
System.out.println(findIndex(arr, sorted[2])); // 3
} else if (choice <= intelligence * 3) {
System.out.println(findIndex(arr, sorted[1])); // 2
} else {
System.out.println(findIndex(arr, sorted[0])); // 0
}
}
static int[] sortedCopy(int[] arr) {
int[] copy = new int[arr.length];
System.arraycopy(arr, 0, copy, 0, arr.length);
Arrays.sort(copy);
return copy;
}
static int findIndex(int[] arr, int val) {
int index = -1;
for (int i = 0; i < arr.length; ++i) {
if (arr[i] == val) {
index = i;
break;
}
}
return index;
}
You can "wipe out" the highest value n-1 times. After this the highest value is the n-th highest value of the original array:
public static void main(String[] args) {
int[] numbers = new int[]{5, 9, 1, 4};
int n = 2; // n-th index
for (int i = 0; i < n - 1; ++i) {
int maxIndex = findMaxIndex(numbers);
numbers[maxIndex] = Integer.MIN_VALUE;
}
int maxIndex = findMaxIndex(numbers);
System.out.println(maxIndex + " -> " + numbers[maxIndex]);
}
public static int findMaxIndex(int[] numbers) {
int maxIndex = 0;
for (int j = 1; j < numbers.length; ++j) {
if (numbers[j] > numbers[maxIndex]) {
maxIndex = j;
}
}
return maxIndex;
}
The complexity is O(n * numbers.length).

find the most popular element in int array in java array {2,3,4,2,3,3,2,9,5} [duplicate]

int[] a = new int[10]{1,2,3,4,5,6,7,7,7,7};
how can I write a method and return 7?
I want to keep it native without the help of lists, maps or other helpers.
Only arrays[].
Try this answer. First, the data:
int[] a = {1,2,3,4,5,6,7,7,7,7};
Here, we build a map counting the number of times each number appears:
Map<Integer, Integer> map = new HashMap<Integer, Integer>();
for (int i : a) {
Integer count = map.get(i);
map.put(i, count != null ? count+1 : 1);
}
Now, we find the number with the maximum frequency and return it:
Integer popular = Collections.max(map.entrySet(),
new Comparator<Map.Entry<Integer, Integer>>() {
#Override
public int compare(Entry<Integer, Integer> o1, Entry<Integer, Integer> o2) {
return o1.getValue().compareTo(o2.getValue());
}
}).getKey();
As you can see, the most popular number is seven:
System.out.println(popular);
> 7
EDIT
Here's my answer without using maps, lists, etc. and using only arrays; although I'm sorting the array in-place. It's O(n log n) complexity, better than the O(n^2) accepted solution.
public int findPopular(int[] a) {
if (a == null || a.length == 0)
return 0;
Arrays.sort(a);
int previous = a[0];
int popular = a[0];
int count = 1;
int maxCount = 1;
for (int i = 1; i < a.length; i++) {
if (a[i] == previous)
count++;
else {
if (count > maxCount) {
popular = a[i-1];
maxCount = count;
}
previous = a[i];
count = 1;
}
}
return count > maxCount ? a[a.length-1] : popular;
}
public int getPopularElement(int[] a)
{
int count = 1, tempCount;
int popular = a[0];
int temp = 0;
for (int i = 0; i < (a.length - 1); i++)
{
temp = a[i];
tempCount = 0;
for (int j = 1; j < a.length; j++)
{
if (temp == a[j])
tempCount++;
}
if (tempCount > count)
{
popular = temp;
count = tempCount;
}
}
return popular;
}
Take a map to map element - > count
Iterate through array and process the map
Iterate through map and find out the popular
Assuming your array is sorted (like the one you posted) you could simply iterate over the array and count the longest segment of elements, it's something like #narek.gevorgyan's post but without the awfully big array, and it uses the same amount of memory regardless of the array's size:
private static int getMostPopularElement(int[] a){
int counter = 0, curr, maxvalue, maxcounter = -1;
maxvalue = curr = a[0];
for (int e : a){
if (curr == e){
counter++;
} else {
if (counter > maxcounter){
maxcounter = counter;
maxvalue = curr;
}
counter = 0;
curr = e;
}
}
if (counter > maxcounter){
maxvalue = curr;
}
return maxvalue;
}
public static void main(String[] args) {
System.out.println(getMostPopularElement(new int[]{1,2,3,4,5,6,7,7,7,7}));
}
If the array is not sorted, sort it with Arrays.sort(a);
Using Java 8 Streams
int data[] = { 1, 5, 7, 4, 6, 2, 0, 1, 3, 2, 2 };
Map<Integer, Long> count = Arrays.stream(data)
.boxed()
.collect(Collectors.groupingBy(Function.identity(), counting()));
int max = count.entrySet().stream()
.max((first, second) -> {
return (int) (first.getValue() - second.getValue());
})
.get().getKey();
System.out.println(max);
Explanation
We convert the int[] data array to boxed Integer Stream. Then we collect by groupingBy on the element and use a secondary counting collector for counting after the groupBy.
Finally we sort the map of element -> count based on count again by using a stream and lambda comparator.
This one without maps:
public class Main {
public static void main(String[] args) {
int[] a = new int[]{ 1, 2, 3, 4, 5, 6, 7, 7, 7, 7 };
System.out.println(getMostPopularElement(a));
}
private static int getMostPopularElement(int[] a) {
int maxElementIndex = getArrayMaximumElementIndex(a);
int[] b = new int[a[maxElementIndex] + 1]
for (int i = 0; i < a.length; i++) {
++b[a[i]];
}
return getArrayMaximumElementIndex(b);
}
private static int getArrayMaximumElementIndex(int[] a) {
int maxElementIndex = 0;
for (int i = 1; i < a.length; i++) {
if (a[i] >= a[maxElementIndex]) {
maxElementIndex = i;
}
}
return maxElementIndex;
}
}
You only have to change some code if your array can have elements which are < 0.
And this algorithm is useful when your array items are not big numbers.
If you don't want to use a map, then just follow these steps:
Sort the array (using Arrays.sort())
Use a variable to hold the most popular element (mostPopular), a variable to hold its number of occurrences in the array (mostPopularCount), and a variable to hold the number of occurrences of the current number in the iteration (currentCount)
Iterate through the array. If the current element is the same as mostPopular, increment currentCount. If not, reset currentCount to 1. If currentCount is > mostPopularCount, set mostPopularCount to currentCount, and mostPopular to the current element.
Seems like you are looking for the Mode value (Statistical Mode) , have a look at Apache's Docs for Statistical functions.
package frequent;
import java.util.HashMap;
import java.util.Map;
public class Frequent_number {
//Find the most frequent integer in an array
public static void main(String[] args) {
int arr[]= {1,2,3,4,3,2,2,3,3};
System.out.println(getFrequent(arr));
System.out.println(getFrequentBySorting(arr));
}
//Using Map , TC: O(n) SC: O(n)
static public int getFrequent(int arr[]){
int ans=0;
Map<Integer,Integer> m = new HashMap<>();
for(int i:arr){
if(m.containsKey(i)){
m.put(i, m.get(i)+1);
}else{
m.put(i, 1);
}
}
int maxVal=0;
for(Integer in: m.keySet()){
if(m.get(in)>maxVal){
ans=in;
maxVal = m.get(in);
}
}
return ans;
}
//Sort the array and then find it TC: O(nlogn) SC: O(1)
public static int getFrequentBySorting(int arr[]){
int current=arr[0];
int ansCount=0;
int tempCount=0;
int ans=current;
for(int i:arr){
if(i==current){
tempCount++;
}
if(tempCount>ansCount){
ansCount=tempCount;
ans=i;
}
current=i;
}
return ans;
}
}
Array elements value should be less than the array length for this one:
public void findCounts(int[] arr, int n) {
int i = 0;
while (i < n) {
if (arr[i] <= 0) {
i++;
continue;
}
int elementIndex = arr[i] - 1;
if (arr[elementIndex] > 0) {
arr[i] = arr[elementIndex];
arr[elementIndex] = -1;
}
else {
arr[elementIndex]--;
arr[i] = 0;
i++;
}
}
Console.WriteLine("Below are counts of all elements");
for (int j = 0; j < n; j++) {
Console.WriteLine(j + 1 + "->" + Math.Abs(arr[j]));
}
}
Time complexity of this will be O(N) and space complexity will be O(1).
import java.util.Scanner;
public class Mostrepeatednumber
{
public static void main(String args[])
{
int most = 0;
int temp=0;
int count=0,tempcount;
Scanner in=new Scanner(System.in);
System.out.println("Enter any number");
int n=in.nextInt();
int arr[]=new int[n];
System.out.print("Enter array value:");
for(int i=0;i<=n-1;i++)
{
int n1=in.nextInt();
arr[i]=n1;
}
//!!!!!!!! user input concept closed
//logic can be started
for(int j=0;j<=n-1;j++)
{
temp=arr[j];
tempcount=0;
for(int k=1;k<=n-1;k++)
{
if(temp==arr[k])
{
tempcount++;
}
if(count<tempcount)
{
most=arr[k];
count=tempcount;
}
}
}
System.out.println(most);
}
}
Best approach will be using map where key will be element and value will be the count of each element. Along with that keep an array of size that will contain the index of most popular element . Populate this array while map construction itself so that we don't have to iterate through map again.
Approach 2:-
If someone want to go with two loop, here is the improvisation from accepted answer where we don't have to start second loop from one every time
public class TestPopularElements {
public static int getPopularElement(int[] a) {
int count = 1, tempCount;
int popular = a[0];
int temp = 0;
for (int i = 0; i < (a.length - 1); i++) {
temp = a[i];
tempCount = 0;
for (int j = i+1; j < a.length; j++) {
if (temp == a[j])
tempCount++;
}
if (tempCount > count) {
popular = temp;
count = tempCount;
}
}
return popular;
}
public static void main(String[] args) {
int a[] = new int[] {1,2,3,4,5,6,2,7,7,7};
System.out.println("count is " +getPopularElement(a));
}
}
Assuming your int array is sorted, i would do...
int count = 0, occur = 0, high = 0, a;
for (a = 1; a < n.length; a++) {
if (n[a - 1] == n[a]) {
count++;
if (count > occur) {
occur = count;
high = n[a];
}
} else {
count = 0;
}
}
System.out.println("highest occurence = " + high);
public static int getMostCommonElement(int[] array) {
Arrays.sort(array);
int frequency = 1;
int biggestFrequency = 1;
int mostCommonElement = 0;
for(int i=0; i<array.length-1; i++) {
frequency = (array[i]==array[i+1]) ? frequency+1 : 1;
if(frequency>biggestFrequency) {
biggestFrequency = frequency;
mostCommonElement = array[i];
}
}
return mostCommonElement;
}
Mine Linear O(N)
Using map to save all the differents elements found in the array and saving the number of times ocurred, then just getting the max from the map.
import java.util.HashMap;
import java.util.Map;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Map;
import java.util.stream.IntStream;
public class MosftOftenNumber {
// for O(N) + map O(1) = O(N)
public static int mostOftenNumber(int[] a)
{
final Map m = new HashMap<Integer,Integer>();
int max = 0;
int element = 0;
for (int i=0; i<a.length; i++){
//initializing value for the map the value will have the counter of each element
//first time one new number its found will be initialize with zero
if (m.get(a[i]) == null)
m.put(a[i],0);
//save each value from the array and increment the count each time its found
m.put(a[i] , (Integer) m.get(a[i]) + 1);
//check the value from each element and comparing with max
if ( (Integer) m.get(a[i]) > max){
max = (Integer) m.get(a[i]);
element = a[i];
}
}
System.out.println("Times repeated: " + max);
return element;
}
public static int mostOftenNumberWithLambdas(int[] a)
{
Integer max = IntStream.of(a).boxed().max(Integer::compareTo).get();
Integer coumtMax = Math.toIntExact(IntStream.of(a).boxed().filter(number -> number.equals(max)).count());
System.out.println("Times repeated: " + coumtMax);
return max;
}
public static void main(String args[]) {
// int[] array = {1,1,2,1,1};
// int[] array = {2,2,1,2,2};
int[] array = {1,2,3,4,5,6,7,7,7,7};
System.out.println("Most often number with loops: " + mostOftenNumber(array));
System.out.println("Most often number with lambdas: " + mostOftenNumberWithLambdas(array));
}
}
Solution 1: Hashmap: O(n)
def most_freq_elem(arr):
frequency = {}
most_frequent, most_count = -1, 0
for num in arr:
frequency[num] = frequency.get(num, 0) + 1
if frequency[num] > most_count:
most_count = frequency[num]
most_frequent = num
return most_frequent
Solution 2: Hashmap + Max: O(n)
def most_freq_elem(arr):
frequency = {}
for num in arr:
frequency[num] = frequency.get(num, 0) + 1
return max(frequency, key=frequency.get)
public static void main(String[] args) {
int[] myArray = {1,5,4,4,22,4,9,4,4,8};
Map<Integer,Integer> arrayCounts = new HashMap<>();
Integer popularCount = 0;
Integer popularValue = 0;
for(int i = 0; i < myArray.length; i++) {
Integer count = arrayCounts.get(myArray[i]);
if (count == null) {
count = 0;
}
arrayCounts.put(myArray[i], count == 0 ? 1 : ++count);
if (count > popularCount) {
popularCount = count;
popularValue = myArray[i];
}
}
System.out.println(popularValue + " --> " + popularCount);
}
below code can be put inside a main method
// TODO Auto-generated method stub
Integer[] a = { 11, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, 4, 1, 2, 2, 2, 2, 3, 4, 2 };
List<Integer> list = new ArrayList<Integer>(Arrays.asList(a));
Set<Integer> set = new HashSet<Integer>(list);
int highestSeq = 0;
int seq = 0;
for (int i : set) {
int tempCount = 0;
for (int l : list) {
if (i == l) {
tempCount = tempCount + 1;
}
if (tempCount > highestSeq) {
highestSeq = tempCount;
seq = i;
}
}
}
System.out.println("highest sequence is " + seq + " repeated for " + highestSeq);
public class MostFrequentIntegerInAnArray {
public static void main(String[] args) {
int[] items = new int[]{2,1,43,1,6,73,5,4,65,1,3,6,1,1};
System.out.println("Most common item = "+getMostFrequentInt(items));
}
//Time Complexity = O(N)
//Space Complexity = O(N)
public static int getMostFrequentInt(int[] items){
Map<Integer, Integer> itemsMap = new HashMap<Integer, Integer>(items.length);
for(int item : items){
if(!itemsMap.containsKey(item))
itemsMap.put(item, 1);
else
itemsMap.put(item, itemsMap.get(item)+1);
}
int maxCount = Integer.MIN_VALUE;
for(Entry<Integer, Integer> entry : itemsMap.entrySet()){
if(entry.getValue() > maxCount)
maxCount = entry.getValue();
}
return maxCount;
}
}
int largest = 0;
int k = 0;
for (int i = 0; i < n; i++) {
int count = 1;
for (int j = i + 1; j < n; j++) {
if (a[i] == a[j]) {
count++;
}
}
if (count > largest) {
k = a[i];
largest = count;
}
}
So here n is the length of the array, and a[] is your array.
First, take the first element and check how many times it is repeated and increase the counter (count) as to see how many times it occurs.
Check if this maximum number of times that a number has so far occurred if yes, then change the largest variable (to store the maximum number of repetitions) and if you would like to store the variable as well, you can do so in another variable (here k).
I know this isn't the fastest, but definitely, the easiest way to understand
import java.util.HashMap;
import java.util.Map;
import java.lang.Integer;
import java.util.Iterator;
public class FindMood {
public static void main(String [] args){
int arrayToCheckFrom [] = {1,2,4,4,5,5,5,3,3,3,3,3,3,3,3};
Map map = new HashMap<Integer, Integer>();
for(int i = 0 ; i < arrayToCheckFrom.length; i++){
int sum = 0;
for(int k = 0 ; k < arrayToCheckFrom.length ; k++){
if(arrayToCheckFrom[i]==arrayToCheckFrom[k])
sum += 1;
}
map.put(arrayToCheckFrom[i], sum);
}
System.out.println(getMaxValue(map));
}
public static Integer getMaxValue( Map<Integer,Integer> map){
Map.Entry<Integer,Integer> maxEntry = null;
Iterator iterator = map.entrySet().iterator();
while(iterator.hasNext()){
Map.Entry<Integer,Integer> pair = (Map.Entry<Integer,Integer>) iterator.next();
if(maxEntry == null || pair.getValue().compareTo(maxEntry.getValue())>0){
maxEntry = pair;
}
}
return maxEntry.getKey();
}
}
Comparing two arrays, I Hope for that this is useful for you.
public static void main(String []args){
int primerArray [] = {1,2,1,3,5};
int arrayTow [] = {1,6,7,8};
int numberMostRepetly = validateArrays(primerArray,arrayTow);
System.out.println(numberMostRepetly);
}
public static int validateArrays(int primerArray[], int arrayTow[]){
int numVeces = 0;
for(int i = 0; i< primerArray.length; i++){
for(int c = i+1; c < primerArray.length; c++){
if(primerArray[i] == primerArray[c]){
numVeces = primerArray[c];
// System.out.println("Numero que mas se repite");
//System.out.println(numVeces);
}
}
for(int a = 0; a < arrayTow.length; a++){
if(numVeces == arrayTow[a]){
// System.out.println(numVeces);
return numVeces;
}
}
}
return 0;
}
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.Map.Entry;
public class MostOccuringEleementInArrayOfIntegers {
public static void main(String[] args) {
int[] arr = { 1, 2, 3, 4, 4, 5, 3, 2, 1, 6, 7, 1, 2, 3, 2 };
Map<Integer, Integer> map = new HashMap<Integer, Integer>();
for (int num : arr) {
if (map.containsKey(num)) {
map.put(num, map.get(num) + 1);
} else {
map.put(num, 1);
}
}
Set<Entry<Integer, Integer>> entrySet = map.entrySet();
int max = 1;
int mostFrequent = 1;
for (Entry<Integer, Integer> e : map.entrySet()) {
// Swapping of the elements who is occuring most
if (e.getValue() > max) {
mostFrequent = e.getKey();
max = e.getValue();
}
}
// Print most frequent element
System.out.println("Most frequent element: " + mostFrequent);
}
}
public class MostFrequentNumber {
public MostFrequentNumber() {
}
int frequentNumber(List<Integer> list){
int popular = 0;
int holder = 0;
for(Integer number: list) {
int freq = Collections.frequency(list,number);
if(holder < freq){
holder = freq;
popular = number;
}
}
return popular;
}
public static void main(String[] args){
int[] numbers = {4,6,2,5,4,7,6,4,7,7,7};
List<Integer> list = new ArrayList<Integer>();
for(Integer num : numbers){
list.add(num);
}
MostFrequentNumber mostFrequentNumber = new MostFrequentNumber();
System.out.println(mostFrequentNumber.frequentNumber(list));
}
}
You can count the occurrences of the different numbers, then look for the highest one. This is an example that uses a Map, but could relatively easily be adapted to native arrays.
Second largest element:
Let us take example : [1,5,4,2,3] in this case,
Second largest element will be 4.
Sort the Array in descending order, once the sort done output will be
A = [5,4,3,2,1]
Get the Second Largest Element from the sorted array Using Index 1. A[1] -> Which will give the Second largest element 4.
private static int getMostOccuringElement(int[] A) {
Map occuringMap = new HashMap();
//count occurences
for (int i = 0; i < A.length; i++) {
if (occuringMap.get(A[i]) != null) {
int val = occuringMap.get(A[i]) + 1;
occuringMap.put(A[i], val);
} else {
occuringMap.put(A[i], 1);
}
}
//find maximum occurence
int max = Integer.MIN_VALUE;
int element = -1;
for (Map.Entry<Integer, Integer> entry : occuringMap.entrySet()) {
if (entry.getValue() > max) {
max = entry.getValue();
element = entry.getKey();
}
}
return element;
}
I hope this helps.
public class Ideone {
public static void main(String[] args) throws java.lang.Exception {
int[] a = {1,2,3,4,5,6,7,7,7};
int len = a.length;
System.out.println(len);
for (int i = 0; i <= len - 1; i++) {
while (a[i] == a[i + 1]) {
System.out.println(a[i]);
break;
}
}
}
}
This is the wrong syntax. When you create an anonymous array you MUST NOT give its size.
When you write the following code :
new int[] {1,23,4,4,5,5,5};
You are here creating an anonymous int array whose size will be determined by the number of values that you provide in the curly braces.
You can assign this a reference as you have done, but this will be the correct syntax for the same :-
int[] a = new int[]{1,2,3,4,5,6,7,7,7,7};
Now, just Sysout with proper index position:
System.out.println(a[7]);

ArrayIndexOutOfBoundsException coming in this array using java?

I have an array of numbers in Java and need to output the ones that consist of only duplicated digits. However, my code throws an ArrayIndexOutOfBoundsException. Where is the problem?
int[] inputValues= {122, 2, 22, 11, 234, 333, 000, 5555, 8, 9, 99};
for (int i = 0; i < inputValues.length; i++) {
int numberLength = Integer.toString(inputValues[i]).length();
// System.out.println(numberLength);
if (numberLength > 1) { //more than one digit in the number
String s1 = Integer.toString(inputValues[i]);
String[] numberDigits = s1.split("");
for (int j = 1, k = 1; j < numberDigits.length; k++) {
if (numberDigits[j].equals(numberDigits[k + 1])) {
System.out.println("Duplicate values are:");
//I need to print 22,11,333,000,5555,99
}
}
}
}
There is no condition to stop the inner loop when k gets too big. j never changes in the inner loop, so j < numberDigits.length will either always be true or always be false.
public static void main(String[] args) {
int[] inputValues={122,2,22,11,234,333,000,5555,8,9,99,1000};
System.out.println("Duplicate values are:");
for (int i = 0; i < inputValues.length; i++) {
String strNumber = new Integer(inputValues[i]).toString();// get string from array
if(strNumber.length()>1) // string length must be greater than 1
{
Character firstchar =strNumber.charAt(0); //get first char of string
String strchker =strNumber.replaceAll(firstchar.toString(), ""); //repalce it with black
if(strchker.length()==0) // for duplicate values length must be 0
{
System.out.println(strNumber);
}
}
}
/*
* output will be
* Duplicate values are:
22
11
333
5555
99
*
*
*/
}
This is what you want.....
This line is the culprit here -
for (int j = 1, k = 1; j < numberDigits.length; k++) {
if (numberDigits[j].equals(numberDigits[k + 1])) {
System.out.println("Duplicate values are:");//i need to print 22,11,333,000,5555,99,etc.
}
}
The loop has a condition that's always true as value of j is always 1. Since k keeps on increasing by 1 for each iteration ( which are infinite btw ), the index goes out of array bounds.
Try -
for (int j = 0, k = 1; k < numberDigits.length; k++) {
boolean isDuplicate = true;
if (!numberDigits[j].equals(numberDigits[k])) {
isDuplicate = false;
break;
}
}
if( isDuplicate ) {
System.out.println("Duplicate values are:"+inputValues[i]);
}
Sorry for joining the party late. I think following is the piece of code you’re are looking for
private int[] getDuplicate(int[] arr) {
ArrayList<Integer> duplicate = new ArrayList<Integer>();
for (int item : arr) {
if(item > 9 && areDigitsSame(item)) {
duplicate.add(item);
}
}
int duplicateDigits[] = new int[duplicate.size()];
int index = 0;
for (Integer integer : duplicate) {
duplicateDigits[index ++] = integer;
}
return duplicateDigits;
}
public boolean areDigitsSame(int item) {
int num = item;
int previousDigit = item % 10;
while (num != 0) {
int digit = num % 10;
if (previousDigit != digit) {
return false;
}
num /= 10;
}
return true;
}
Now , use it as below
int[]inputValues={122,2,22,11,234,333,000,5555,8,9,99};
int[] duplicates = getDuplicate(inputValues);
That's all
Enjoy!
public static void main(String[] args) {
String[] inputValues={"122","2","22","11","234","333","000","5555","8","9","99"};
System.out.println("Duplicate values are:");
for (int i = 0; i < inputValues.length; i++) {
String strNumber = inputValues[i];// get string from array
if(strNumber.length()>1) // string length must be greater than 1
{
Character firstchar =strNumber.charAt(0); //get first char of string
String strchker =strNumber.replaceAll(firstchar.toString(), "0"); //repalce it with 0
if(Integer.parseInt(strchker)==0) //if all values are duplictae than result string must be 0
{
System.out.println(strNumber);
}
}
}
}
// /// result will be
/* Duplicate values are:
22
11
333
000
5555
99
*/
if you want int array then you will not able to get "000" as duplicate value.
# line 13: the s1.split("") results to [, 1, 2, 2] for 122 . Hence your numberDigits.length is 4. The loop runs from j = 1 to 3 ( j < numberDigits.length); hence the numberDigits[k + 1 ] is evaluated for index 4 which is unavailable for [, 1, 2, 2].
Another point is worth noting is int[]inputValues will always store 000 as 0 only.
The below mentioned method will take a integer number and will return true and false based on your requirement. It will use xor operator to check repetitive digits.
private static boolean exorEveryCharacter(int currentValue) {
int result = 0;
int previousNumber = -1;
while (currentValue != 0) {
int currentNumber = currentValue % 10;
if(previousNumber == -1){
previousNumber = currentNumber;
}
else{
result = previousNumber ^ currentNumber;
}
currentValue /= 10;
}
return result == 0;
}

Categories

Resources