I am almost at end of code. I am supposed to find number of times numbers appeared in a given array. The for loop is not working as expected.
They contain numbers in an array, I am able to extract individual numbers which are repeating. Then I am trying to find how many time that an individual number is appeared by using for loop and store it into another array which will give me the count.
Everything is declared like d[], b[], c[]
for (i = 0; i < k; i++) {
for (j = 0; j < l; j++) {
if (d[i] == c[j]) {
b[i]++;
}
}
}
Expected output should be, like if if's condition to be true, b[i] should increment the number of times a number appeared but it is giving me array of ones, like it is only passing through the if condition once per i.
You can do that using for example a Hashtable saving the array numbers as keys and the number of repetitions as value. This function receive an array of Integers, and returns the Hashtable with the repetitions:
public static Hashtable<Integer, Integer> getRepitedNumbers( Integer[] numbers) {
Hashtable<Integer, Integer> Result = new Hashtable<Integer, Integer>();
for( int i = 0; i < numbers.length; i++) {
if( Result.containsKey( numbers[ i])) {
//If the current number is saved in the hashtable, you need to increment the
//value (repetitions counter for this number)
Result.put( numbers[ i], Result.get( numbers[ i]) + 1);
} else {
//If the current number doesn't exist, is the first occurrence.
Result.put( numbers[ i], 1);
}
}
//At the end you have a hashtable with each number and the number of occurrences
return Result;
}
https://docs.oracle.com/javase/8/docs/api/java/util/stream/Collectors.html
public static void main(String[] args) {
List<Integer> listOfIntegers = Arrays.asList(1, 2, 3, 1, 2, 3, 3, 3, 3, 8, 9);
Map<Integer, Long> integerToCount = listOfIntegers.stream().collect(Collectors.groupingBy(it -> it, Collectors.counting()));
System.out.println(integerToCount);
}
What about using Streams:
public static Map<Integer, Long> countItems(Integer[] arr) {
return Arrays.stream(arr).collect(Collectors.groupingBy(Function.identity(), Collectors.counting()));
}
I have an array containing some duplicate elements like this :
find the first duplicate number for which the second occurrence has the minimal index. In other words, if there are more than 1 duplicated numbers, return the number for which the second occurrence has a smaller index than the second occurrence of the other number does. If there are no such elements, return -1
For a = [2, 1, 3, 5, 3, 2], the output should be
firstDuplicate(a) = 3.
There are 2 duplicates: numbers 2 and 3. The second occurrence of 3 has a smaller index than the second occurrence of 2 does, so the answer is 3.
I tried this :
int firstDuplicate(int[] a) {
Set<Integer> set = new HashSet<>();
Map<Integer, Integer> hm = new HashMap<Integer,Integer>();
Map.Entry<Integer, Integer> min = null;
for(int i=0;i<a.length;i++){
// if(!hm.containsKey(a[i]))
hm.put(a[i],i);
}
for(Map.Entry<Integer,Integer> entry : hm.entrySet()){
if(min == null || entry.getValue() < min.getValue()){
min = entry;
}
}
return min == null ? new Integer(-1) : min.getKey();
}
It's not working out, but I got another solution online which is like this :
int firstDuplicate(int[] a) {
Set<Integer> set = new HashSet<>();
Map<Integer, Integer> hm = new HashMap<Integer,Integer>();
Map.Entry<Integer, Integer> min = null;
for(int i=0;i<a.length;i++){
if(set.add(a[i])==false && !hm.containsKey(a[i]))
hm.put(a[i],i);
}
for(Map.Entry<Integer,Integer> entry : hm.entrySet()){
if(min == null || entry.getValue() < min.getValue()){
min = entry;
}
}
return min == null ? new Integer(-1) : min.getKey();
}
Can anyone please explain me the use of Hashset here, as it doesn't allow the duplicates so how that if condition will be workable.
The reason your first attempt failed is that you add the array elements as keys to the Map without checking if they are already there, which means you can't know if there are any duplicates by the time you finish populating the Map.
The alternative code you found does something different. It uses the Set to determine if the current array element already appeared earlier in the array, and if that's the case, it adds it as key to the Map only if it's not already there. This means that the Map will only contain elements that appear multiple times in the array, and the index associated with each element is the occurrence of the first duplicate. I.e. for the array {2, 1, 3, 5, 3, 2}, the Map will contain {2=5, 3=4}. Then it will return the key having the smallest value (which corresponds with the index of the first duplicate).
However, the Map is unnecessary, since you only need to find one duplicate, not all of them. Use the Set to locate the first duplicate and return it:
int firstDuplicate(int[] a)
{
Set<Integer> set = new HashSet<>();
for(int i=0;i<a.length;i++){
if(!set.add(a[i])) {
return a[i];
}
}
return -1; // no duplicates found
}
This relies on set.add() returning false if the Set already contains the element you wish to add. Once it returns false for the first time, you found the first duplicate.
I would strongly recommend you to try this to get the correct results
you can make it more efficient time complexity O(n)
int firstDuplicate(int[] a){
int n = a.length;
for(int i=0; i<n; i++)
{
if(a[Math.abs(a[i])-1]<0) return Math.abs(a[i]);
else a[Math.abs(a[i])-1] = - a[Math.abs(a[i])-1];
}
return -1;
}
int firstDuplicate(int[] a){
int n = a.length;
for(int i=0; i<n; i++)
{
if(a[Math.abs(a[i])-1]<0) return Math.abs(a[i]);
else a[Math.abs(a[i])-1] = - a[Math.abs(a[i])-1];
}
return -1;
}
I will explain why and how this one works.
It's important that this constrain: 1 ≤ a[i] ≤ a.length is present, meaning that in an array like this: a = [2,8,2] this algorithm WILL NOT work because 8 is bigger than a.length in this case 3.
You'll find the explanation here as well:
Hashmap
This solution follows the idea of a hashmap. Another structure where you count hash[arr[i]-1]++ the number of occurrences for any given index i in the array. Example:
If you have arr[2,1,3,5,3,2] hashmap will begin in an 6 zero array: hashmap[0,0,0,0,0,0] because that's the size of arr. As the algorithm progress it will sum +1 in the position arr[i]-1. It's using the value as the index of the sum. At then end you get: arr[1,2,2,0,1,0].
This has O(n) in time complexity because it runs the full arr, and O(n) in time because it runs the array at least 1 time.
Without Hashmap
The idea of the algorithm above is that you don't need the extra structure of a hashmap but can use the same array to count the frequency. This might lead to a problem. Let i-th element be a or (arr[i]=a) then the count should be stored at arr[arr[i]-1] or (arr[a-1]), but when the frequency will be stored the element will be lost.
Example iteration:
a[2,1,3,5,3,2] -> a[2,1,3,5,3,2]
a[2,1,3,5,3,2] -> a[1,1,3,5,3,2]
a[1,1,3,5,3,2] -> a[1,1,1,5,3,2]
a[1,1,1,5,3,2] -> a[1,1,1,5,1,2] As you can see we lost the value of 3 when we read 5 as it stored the frequency in arr[arr[4]-1] or (arr[5-1]).
Solve the missing problem
To solve this problem first we put replace the i-th element with arr[arr[i]-1] or (arr[a-1]) then put -1 at array arr[arr[i]-1] or (arr[a-1]).
The algorithm:
Traverse the array from start to end.
For each element check if the element is less than or equal to zero or not. If negative or zero skip the element as it is frequency.
If an element (a = arr[i] – 1) is positive, then check if arr[a] is positive or not. If positive then that means it is the first occurrence of a in the array and replace arr[i] with arr[a], and assign arr[a] = -1. If arr[a] is negative, then it is not the first occurrence, then update arr[a] as arr[a]-- and update arr[i] as arr[i] = 0. You use an auxiliary value to save arr[a] that will be used in the next iteration.
Again, traverse the array and print i+1 as value and arr[i] as frequency.
Example iteration:
a[2,1,3,5,3,2] -> a[1,1,3,5,3,2] -> a[1,-1,3,5,3,2]
a[1,-1,3,5,3,2] -> a[1,-1,3,5,3,2] -> a[1,-1,-1,5,3,2]
a[1,-1,-1,5,3,2] -> a[1,-1,-1,0,3,2]
a[1,-1,-1,0,3,2] -> a[1,-1,-1,0,-1,2] -> a[1,-1,-2,0,-1,2]
a[1,-1,-2,0,-1,2] -> a[1,-1,-2,0,-1,0]
a[1,-1,-2,0,-1,0] -> a[1,-2,-2,0,-1,0]
firstDuplicate
After knowing this we can now grasp how firstDuplicate works. The idea is not to count the frequency but instead just print the index that has already a negative in frequency. When we get a negative frequency we return.
So running the algorithm we get:
With if(a[2-1]<0) or if(1<0) this comparation is between arr[arr[0]-1] or (arr[1]) and 0 so we don't return. a[2,1,3,5,3,2] -> a[2,-1,3,5,3,2]
With if(a[1-1]<0) or if(2<0) we don't return a[2,-1,3,5,3,2] -> a[-1,-1,3,5,3,2].
With if(a[3-1]<0) or if(3<0) we don't return. a[-1,-1,3,5,3,2] -> a[-2,-1,-3,5,3,2]
With if(a[5-1]<0) or if(3<0) we don't return. a[-2,-1,-3,5,3,2] -> a[-2,-1,-3,5,-3,2]
With if(a[3-1]<0) or if(-3<0) we return.
All of this is based on the idea that element-1 is the index.
You can use java 8 with lambda and stream.
Here is the code in one line :
Set<Integer> allItems = new HashSet<>();
Arrays.stream(a).filter(i -> !allItems.add(i)).findFirst().orElse(-1)
it returns what you expect
There are two ways to implement this problem, by using a HashSet with time complexity o(n) and by using nested loops o(n2)
for(int i = 0; i < a.length; i++){
for(int j = i +1; j < a.length; j++){
if(a[i] == a[j]){
System.out.println(a[i]);
return;
}
}
}
Or you can make it more efficient time complexity O(n)
int index -1;
Set<Integer> hashSet = new HashSet<Integer>();
for(int i = a.length-1; i >= 0; i--){
if(hashSet.contains(a[i])){
index = i;
}else{
hashSet.add(a[i]);
}
}
System.out.println(a[index]);
int firstDuplicate(int[] a)
{
int DupIndex = 0;
int DupValue = 0;
for (int i = 0; i < a.Length; i++)
{
for (int j = i + 1; j < a.Length; j++)
{
if (a[i] == a[j])
{
if (j < DupIndex)
{
DupIndex = j;
DupValue = a[i];
}
else if (DupIndex == 0)
{
DupIndex = j;
DupValue = a[i];
}
}
};
};
return (DupValue == 0) ? -1 : DupValue;
}
public static void main(String[] args){
int array[]={2, 1, 3, 5, 3, 2};
int tempArray[]=new int[array.length];
int index=0;
while(index< array.length){
if(++(tempArray[array[index]])==2)
break;
index++;
}
if(index> array.length){
System.out.println("No Duplicate");
}else {
System.out.println("First Duplicate " + array[index]);
}
}
Use counting sort, sweet and simple :)
Java implementation
Time complexity O(n) -- Linear
Space Complexity O(n) -- Linear
//Approach
//run a loop and try to insert it into a map.
//check if map contains key for arr[nextValue]
//if contains key, break loop and return value.
//if not, keep on adding in the map.
import java.util.HashMap;
import java.util.Map;
public class ReturnFirstRecurringCharacter {
public static void main(String[] args) {
int[] arr1 = {2,5,5,2};
Integer recurringNumber = checkForRecurringNumber(arr1);
if (recurringNumber != null) {
System.out.println(recurringNumber);
} else {
System.out.println("Undefined");
}
}
private static Integer checkForRecurringNumber(int[] arr1) {
try {
if (arr1 != null) {
Map<Integer, Integer> dataMap = new HashMap<>();
for (int i = 0; i < arr1.length; i++) {
if (dataMap.containsKey(arr1[i])) {
return arr1[i];
}
dataMap.put(arr1[i], i);
}
}
} catch (Exception e) {
System.out.println(e);
e.getStackTrace();
}
return null;
}
}
JS solution:
function solution(a) {
const map = {};
for(let i=0; i<a.length; i++) {
if(map[a[i]]) {
if(map[a[i]][0] === 1) {
map[a[i]][0]++ ;
map[a[i]][1] = i;
}
} else {
map[a[i]] = [1, i];
}
}
const data = Object.keys(map).filter(key => map[key][0] == 2).map(el => parseInt(el));
let smallest = Infinity;
let smallestData = -1;
for(let i=0; i<data.length; i++) {
if(map[data[i]][1] < smallest) {
smallest = map[data[i]][1];
smallestData = data[i];
}
}
return smallestData;
}
Solution in Javascript
function solution(a) {
let i = -1;
while (++i < a.length)
if (a.indexOf(a[i]) !== i)
return a[i];
return -1;
}
console.log(solution([2, 1, 3, 5, 3, 2])); // 3
console.log(solution([2, 2])); // 2
console.log(solution([2, 4, 3, 5, 1])); // -1
i want to write a recursive method that prints the sum of occurrences in an array without using loops in the method.
for example if the method get array - arr{1,1,2,3,3,3,3}
the method will print 1:2 2:1 3:4
for this i write a few method
first method that sort the array
seconed method that get array index and the number in this index and return the next index of different number for example to the array above the funcJump(arr,1,1)
will return 3 beacuse thats the first index of different num for 1.
what i think to do to solve this problem is first use the function to sort the array and then to write two punctions
public static void printFrequencies(int[]arr)//will print
public static int printFrequencies(int[]arr,int ix){//scan the array and send
to the void function the sum of occurences
what i think is to use the function "jump" to get the different indexes and send them to the void function for print but i really stuck to apply this way of thinking to my program.
what do you think thats a good idea?
how can i applay this in my program?
public void printFrequencies(Integer[] array){
Map<Integer, Integer> map = new HashMap<Integer,Integer>();
for(int i = 0 ; i<array.length;i++){
Integer temp = array[i];
Integer count = map.get(temp);
if(null == count){
map.put(temp, 1);
}else{
map.put(temp, map.get(temp)+1);
}
}
for(Integer key : map.keySet()){
System.out.println(key+":"+map.get(key));
}
}
I read your code, and I think it's better to understand, and in order to remove duplicate items, I used map.
public class Part01 {
public static void main(String[] args) {
int[] nums = {1,2,2,1,1,3,3,4};
Part01 part01 = new Part01();
part01.countAllNumber(nums);
}
public int countNumber(int[] nums,int num){
int count = 0;
for(int i = 0;i < nums.length;i++){
if(nums[i] == num)
count++;
}
return count;
}
public void countAllNumber(int[] nums){
Map<Integer,Integer> map = new HashMap<Integer,Integer>();
for(int i = 0;i < nums.length;i++){
int count = countNumber(nums, nums[i]);
map.put(nums[i], count);
}
for(Integer key : map.keySet()){
System.out.println(key+":"+map.get(key));
}
}
}
I am using this method with the intentions of finding the most common element in an array. It works most of the time but for some reason it doesn't always work. I would also like it to be able to store if there are 2 numbers tied for most common but I am unsure how to do so.
Here is the code for the method: (The variable size is the size of the array)
public static int mostCommon(int size) {
int mostCommon = 0, mostCommonCount = 0, currentCount = 0;
for (int i = 1; i < size; i++) {
if (array[i - 1] == array[i]) {
currentCount++;
if (currentCount > mostCommonCount) {
mostCommonCount = currentCount;
mostCommon = array[i];
}
}
else
currentCount = 0;
}
return mostCommon;
}
This code is in the main and prints out the most common element:
if (mostCommon(size) == 0)
System.out.println("\nAll Elements In Your Array Occur Equally");
else
System.out.println("\nThe Most Common Element In Your Array Is: " + mostCommon(size));
I would really appreciate the help. Thanks!
Guessing this is irrelevant now but thought I would answer anyway.
I don't fully understand why you would pass the size of the array in but not the array itself, anyway, I have a solution, slightly modified from your method signature but if it is still needed then it can be modified to suit your exact situation.
public static Set<Integer> mostCommon()
{
int[] array = new int[] {1,2,3,4,5,5,4,3,4};
Map<Integer, Integer> counts = new HashMap<Integer,Integer>();
Set<Integer> highestCount = new TreeSet<Integer>();
//loop through the array to count common values
for(int numInArray : array)
{
//if number in array already been seen
if(counts.containsKey(numInArray))
{
counts.put(numInArray, counts.get(numInArray)+1);
}
//else set it at one
else
{
counts.put(numInArray, 1);
}
}
//loop through map to count highest occurences
int maxValue = 0;
int maxKey = 0;
for(Integer mapKey : counts.keySet())
{
int value = counts.get(mapKey);
//if value is greater than maxValue then set maxVale=value, also clear highestCount as they are lower now
if(value > maxValue)
{
highestCount.clear();
maxValue = value;
maxKey = mapKey;
}
//if value is the same as maxValue then store it in list, this will allow us to get two of the same max occurences
else if(value == maxValue)
{
highestCount.add(mapKey);
}
}
highestCount.add(maxKey);
System.out.println("counts " + counts);
System.out.println("final answer " + highestCount);
return highestCount;
}
I have tested various values in the array and it seems to work for all I tried.
This is by no means the most efficient method it is just a solution that works.
edit: Seen your other question and the code you posted that was this method and yours works much better than this answer
You can get logic by this solution and language use to solve this problem is SWIFT 4.2
var arrColor = ["red","green","blue","green","red","green","blue","green","red","green","blue","green","blue","green","red","green","blue","blue","green","red","green","blue","blue","blue","blue","blue"]
func mostCommonArray(array:[String])->[String]{
var commonArr = [String]()
var dictColor = [String:Int]()
for color in array{
if let count = dictColor[color]{
dictColor[color] = count + 1
}
else{
dictColor[color] = 1
}
}
let highestValue = dictColor.values.max()
for (color,count) in dictColor{
if dictColor[color] == highestValue{
commonArr.append(color)
}
}
return commonArr
}
I'm trying to count how many duplicate items are in an array.
Example:
[0, 2, 0] would return 2, [0, 0, 0] would return 3, [0, 1, 2] = 0
So far I have it working for when all three items are equal, but I'm not sure why it's returning one less than what it should for 2 items being the same.
int equal = 0;
for(int i = 0; i < recent.length; i++) {
for(int j = i; j < recent.length; j++) {
if(i != j && recent[i].equals(recent[j])) {
equal++;
}
}
}
Your algorithm is flawed in the following way: for every element in the array you look at all the elements after that element and if they happen to be equal, you increase the counter. However when you have 3 same elements, you count the last one twice - when you run internal loop for first and for second element. Moreover you never count the first element.
So it works by accident for [0, 0, 0] but doesn't work for other inputs.
I think that having nested loops is quite inefficient. You should be able to do it in o(n) rather than o(n^2).
If you time yours against the following...
public void run() {
int[] array = createRandomArray(2000000, 1000000);
System.out.println(countNumDups1(array));
}
private int[] createRandomArray(int numElements, int maxNumExclusive) {
int[] array = new int[numElements];
Random random = new Random();
for (int i = 0; i < array.length; i++) {
array[i] = random.nextInt(maxNumExclusive);
}
return array;
}
private int countNumDups1(int[] array) {
Map<Integer, Integer> numToCountMap = new HashMap<>();
for (int i = 0; i < array.length; i++) {
Integer key = array[i];
if (numToCountMap.containsKey(key)) {
numToCountMap.put(key, numToCountMap.get(key) + 1);
}
else {
numToCountMap.put(key, 1);
}
}
int numDups = 0;
for (int i = 0; i < array.length; i++) {
Integer key = array[i];
if (numToCountMap.get(key) > 1) {
numDups++;
}
}
return numDups;
}
I think you'll find the above is much faster even considering the horrible inefficiency of autoboxing and object creation.
The code you gave counts equivalences, so it adds one every time an element equals another element.
It sounds like what you want is the number of duplicate items, which is the same as (length - number of items that don't have a duplicate). I will call the latter "uniqueItems".
I would recommend the following:
// set of every item seen
Set<Integer> allItems = new HashSet<Integer>();
// set of items that don't have a duplicate
Set<Integer> uniqueItems = new HashSet<Integer>();
for(int i = 0; i < recent.length; i++) {
Integer val = i;
if(allItems.contains(val)) {
// if we've seen the value before, it is not a "uniqueItem"
uniqueItems.remove(val);
} else {
// assume the value is a "uniqueItem" until we see it again
uniqueItems.add(val);
}
allItems.add(val);
}
return recent.length - uniqueItems.size();
The below code works perfectly to find the duplicates
int array[] = {1,2,3,4,5,2,3,4,5,3,4,5,4,5,5};
HashMap<Integer,Integer> duplicates = new HashMap<Integer,Integer>();
for(int i=0; i<array.length; i++)
{
if(duplicates.containsKey(array[i]))
{
int numberOfOccurances = duplicates.get(array[i]);
duplicates.put(array[i], (numberOfOccurances + 1));
}else{
duplicates.put(array[i], 1);
}
}
Iterator<Integer> keys = duplicates.keySet().iterator();
System.out.print("Duplicates : " );
while(keys.hasNext())
{
int k = keys.next();
if(duplicates.get(k) > 1)
{
System.out.print(" "+k);
}
}
You are counting the number of pairs of indices that have equal values. What you claim to want is the total size of all sets of equal elements that have more than one element in them.
I would use a Map or similar to count the total number of appearances of a given value. At the end, iterate over the key values adding the number of appearances for each key that has more than one appearance.
int intArray[] = {5, 1, 2, 3, 4, 5, 3, 2};
String val = "";
int c = 1;
Map<Integer, Integer> nwmap = new HashMap<Integer, Integer>();
for (int i = 0; i < intArray.length; i++) {
Integer key = intArray[i];
if(nwmap.get(key) != null && nwmap.containsKey(key)){
val += " Duplicate: " +String.valueOf(key)+"\n";
}else{
nwmap.put(key, c);
c++;
}
}
LOG.debug("duplicate value:::"+val);
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Map;
public class ArrayDuplicateCount {
/**
* #author:raviteja katari
*/
public static void main(String[] args) {
int intArray[] = {5, 1,4,4,4,5,1,2,1,2,5,5};
//for counting duplicate items
int c = 0;
//creating map collection to hold integers as keys and Cont as value
Map<Integer, Integer> nwmap = new LinkedHashMap<Integer, Integer>();
for (int i = 0; i <intArray.length; i++) {
//Assigning array element to key
Integer key = intArray[i];
//this code checks for elemnt if present updates count value else
//put the new Array elemnt into map and increment count
if(nwmap.containsKey(key)){
//updating key value by 1
nwmap.put(key, nwmap.get(key) + 1);
}else{
//Adding new array element to map and increasing count by 1
nwmap.put(key, c+1);
}
}
//printing map
System.out.println(nwmap);
}
}
output:
{5=4, 1=3, 4=3, 2=2}
public void TotalduplicateNumbers {
int a[] = {2,8,2,4,4,6,7,6,8,4,5};
Map<Integer,Integer> m = new HashMap<Integer,Integer>();
for(int i=0;i<a.length;i++){
if(!m.containsKey(a[i]))
{
m.put(a[i], 1);
}
else
{
m.put(a[i], (m.get(a[i])+1));
}
}
for(Integer i:m.keySet()){
System.out.println("Number "+i+" "+"Occours "+m.get(i)+" time,");
}
}
We have an array containing 11 numbers, The logic is to create a map using these no. in which KEYS of map would be the actual number that must be entered by user and no. of occournce of that actual no. would be the value of that KEY. Here, containsKey() method checks whether the map contain that key already and return boolean value true or false as applied.If it does not contain then add that key into the map and its corresponding value should be 1 otherwise key would have already be contained in map so get the value of that key using get() and increment it by 1. Finally printing the map.
OUTPUT:--
Number 2 Occours 2 time,
Number 4 Occours 3 time,
Number 5 Occours 1 time,
Number 6 Occours 2 time,
Number 7 Occours 1 time,
Number 8 Occours 2 time,