I'm trying to figure out how to check if all 23 numbers in my array (the numbers are randomly generated) are NOT equal to each other but I can't figure out how to do it without a super ridiculous if statement. Is there any other way I could do it? Another option would be to check if any two numbers in the array are equal but the reason I posed the question the way I did was because I figured checking the equality of each pair would be harder than checking the inequality of all the numbers.
Your problem can be solved with two nested for-loops
public static boolean hasDuplicates(int[] array)
{
for (int i = 0, length = array.length; i < length; i++)
{
int val = array[i];
for (int j = 0; j < i; j++)
{
if (array[j] == val)
{
return true;
}
}
}
return false;
}
The first loop loops over every element in the array, while the second one checks if any of the values before the index of the outer loop are equal to the value at array[i]. You can safely use j < i for performance and to ensure that it doesn't return true on the same element.
You can use an algorithm like the following to test whether every array element is unique:
boolean everyNumberIsUnique(int[] numbers) {
for(int i = 0; i < numbers.length; i++) {
for(int j = i + 1; j < numbers.length; j++) {
if(numbers[i] == numbers[j]) return false;
}
}
return true;
}
It simply compares each number against each other and returns false if any two numbers are equal.
If you have a relatively low upper bound on your numbers (say less than 1 million) and don't really care about memory usage, you can just create a boolean array and set each element to true if its index is in your array. This is O(n), so its probably the best you can do, but, admittedly, you have to meet the above criteria.
public boolean allDifferent(int[] numbers)
{
//everything in the array defaults to false
boolean[] array = new boolean[upperBound+1];
for (int i = 0; i < numbers.length; i++)
{
if (array[numbers[i]]) //if we've already seen this number (aka duplicate)
{
return false;
}
array[numbers[i]] = true; //note that we have now seen this number
}
return true;
}
Related
I am unsure as to why my code does not give the correct outputs for the test data which has been provided to me.
Write a procedure 'allDistinct' that takes an array of objects and returns true iff they are all distinct (no two identical).
Your procedure must work for all classes, You may type it using a variable type T
<T> boolean allDistinct(T[] a)
{
boolean r = true;
for (int i = 0; i < a.length; i++)
{
for (int j = 0; j < a.length; j++)
{
if (a[i] == a[j])
{
r = false;
}
}
}
return r;
}
I have tried using .equals() instead of == but this resulted in no change and I am not sure why it is still incorrect.
First, you were right, you absolutely need to use equals and not == (see, e.g., What is the difference between == and equals() in Java?).
Second, as Umeshwaran's answer's states, by "naively" looping over i and j, you have multiple cases where i and j are the same, and thus you'd be comparing an object to itself and wrongly returning false.
Third, while this has no effect on the correctness of the solution, from a performance perspective you should use the early return idom. Once you found a duplicate value there's no chance of it getting "unduplicated", so it's pointless to continue iterating over the rest of the array:
<T> boolean allDistinct(T[] a) {
for (int i = 0; i < a.length; i++) {
for (int j = i + 1; j < a.length; j++) { // changed j=0 to j=i+1
if (a[i] == a[j]) {
return false; // Early return
}
}
}
return true;
}
Having said all of that, it may be easier to let Java's Sets do the heavy lifting for you, although this is tradeoff between runtime complexity and memory complexity:
<T> boolean allDistinct(T[] a) {
Set<T> tempSet = new HashSet<>(Arrays.asList(a));
return tempSet.size() == a.length;
}
This is very simple task.
First of all, you should compare two objects with type T using equals().
Your task is to put all data into a HashSet collection. And if the final size of the collection is less thant the length of the array, it means, that the array contains not distinct values.
public static <T> boolean isAllDistinct(T[] arr) {
Set<T> unique = new HashSet<>();
for (T item : arr)
if (!unique.add(item))
return false;
return true;
}
or using Stream
public static <T> boolean isAllDistinct(T[] arr) {
return Arrays.stream(arr).collect(Collectors.toSet()).size() == arr.length;
}
Your code is correct , but you have made a minor mistake which is making it false .
<T> boolean allDistinct(T[] a)
{
boolean r = true;
for (int i = 0; i < a.length; i++)
{
for (int j = i+1; j < a.length; j++) // changed j=0 to j=i+1
{
if (a[i] == a[j])
{
r = false;
}
}
}
return r;
}
I have changed j=0 to j=i+1 , because when looping again , you are checking if both first elements are equal and it is failing
Is there a better way to solve this problem through nested loops, or Hashtable (or any other methods)are the only way to deal with this error?
class Solution {
public boolean containsDuplicate(int[] nums) {
// traversing the array to find an element equal to the chosen element
for (int i = 0; i < nums.length; i++){
// now after one element is chosen traversing the rest to find its equal
for (int j = i+1; j < nums.length; j++){
int dupli = nums[i];
if (dupli == nums [j]){
return true;
}
}
}
return false;
}
}
I'm trying to implement insertion sort and it works for one weird implementation but in reverse order. The same goes for another selection sort I was trying but it working the same way.
void insertionSort(ArrayList<T> genericAList) {
for (int n = 1; n < genericAList.size(); n++) {// go from start to end
// n=genericList.size
//n is primary index, j is secondary ind
for (int j = 0; j < n; j++) { // This sorts in descending order
//WHY DOES THIS NOT WORK?? for (int j = n-1; j>0; j--) {
if (genericAList.get(n).compareTo(genericAList.get(j)) == 1) {
T ncopy = genericAList.get(n);
genericAList.set(n, genericAList.get(j));
genericAList.set(j, ncopy);
}
}
//unsuccessfully trying to copy the array to reverse the order
ArrayList<T> copy = new ArrayList<>();
for (int i = genericAList.size() - 1; i >= 0; i--) { // start from end of old
copy.add(genericAList.get(i));
}
// genericAList=copy;
}
// return clone();
}
Note that compareTo is not guaranteed to return -1 or 1 for larger or smaller.
It returns 0 if they are the same, and then a number larger or smaller than 0 if they are different.
Imagine the pseudo-code for a primitive form of this - if we're comparing two numbers for instance we might do this:
public int compareTwoNumbers(x, y) {
return x - y;
}
So comparing 5 and 3 will give you -2 or 2 (for instance, depending on which way around they are).
The for loop should be int j = n; j > 0; j--, the == 1 should be > 0, and you're comparing/swapping the element at n when it should be j - 1.
Hi so I am supposed to count the number of unique elements after an array sort excluding duplicates but i'm getting the wrong output.
In in = new In(args[0]);
int[] whitelist = in.readAllInts();
Arrays.sort(whitelist);
int count = 0;
for (int i = 0; i < whitelist.length; i++) {
if (whitelist[i] == whitelist[count]) {
count++;
}
}
while (!StdIn.isEmpty()) {
int key = StdIn.readInt();
rank(key, whitelist);
}
System.out.println(count);
}
}
expected output: java InstrumentedBinarySearch tinyW.txt < tinyT.txt
65
got: 16
Did i count the number of duplicates or something?
int flag = 0;
int count = 0;
for (int i = 0; i < whitelist.length; i++) //Element to be checked for
{
for (int j=0; j< whitelist.length ; j++) //Loop that goes through the whole array
{
if (whitelist[i] == whitelist[j]) //checks if there are duplicates
{
flag++; // count
}
}
if( flag==1) //There should be only 1 instance of the element in the array and that is the element itself
{
System.out.println(whitelist[i]); //displays unique element
count++; // Keeps count
}
}
This algorithm counts how many different unique numbers there are in the array. A number appearing more than once will only count for 1. I am assuming this is what you mean, as opposed to "numbers which appear exactly once".
There is a more trivial way to do it, as proposed in another answer, but it requires a nested for-loop and therefore executes in quadratic complexity. My algorithm below attempts to solve the problem in linear time proportional to the array size.
int uniquesFound = 0;
// Assume that array is sorted, so duplicates would be next to another.
// If we find duplicates, such as 12223, we will only count its last instance (i.e. the last '2')
for (int i = 0; i < whitelist.length; i++) {
// If we are at the last element, we know we can count it
if (i != whitelist.length - 1) {
if (whitelist[i] != whitelist[i+1]) {
uniquesFound++;
}
else {
// Nothing! If they are the same, move to the next step element
}
} else {
uniquesFound++;
}
}
For instance, given the array:
{1,2,3} this will yield 3 because there are 3 unique numbers
{1,2,3,3,3,4,4,4,5} this will yield 5 because there are still 5 unique numbers
First let's take a look at your loop:
for (int i = 0; i < whitelist.length; i++) {
if (whitelist[i] == whitelist[count]) {
count++;
}
}
You should be comparing consecutive elements in the list, like whitelist[0] == whitelist[1]?, whitelist[1] == whitelist[2]?, whitelist[3] == whitelist[4]?, etc. Doing whitelist[i] == whitelist[count] makes no sense in this context.
Now you have two options:
a. Increment your counter when you find two consecutive elements that are equal and subtract the result from the total size of the array:
for (int i = 0; i < whitelist.length - 1; i++) {
if (whitelist[i] == whitelist[i + 1]) {
count++;
}
}
int result = whitelist.length - count;
b. Change the condition to count the transitions between consecutive elements that are not equal. Since you are counting the number of transitions, you need to add 1 to count in the end to get the number of unique elements in the array:
for (int i = 0; i < whitelist.length - 1; i++) {
if (whitelist[i] != whitelist[i + 1]) {
count++;
}
}
int result = count + 1;
Note that, in both cases, we loop only until whitelist.length - 1, so that whitelist[i + 1] does not go out of bounds.
I have an array:
int[] anArray = new int[6];
What if the array contained 1,4,5,4,4? How can I get the most matches? In this case 4 is the most frequent number, and there are three of them, so the function should return 3.
Or if I have 1,2,1,2,3 it should return 2.
Or if I have 4,0,1,2,3 it should return 1.
I really can't figure it out. I tried this:
public static int getCorrectMatches(int[] flowers) throws Exception {
int highest = 0;
for(int index = 0; index < 5; index++) {
int count = countMatches(flowers, index);
if(count > highest) {
highest = index;
}
}
return highest;
}
public static int countMatches(int[] array, int match) throws Exception {
int count = 0;
for(; count < array.length && array[count] == match; count++);
return count;
}
Which didn't work. I'd appreciate any help.
Iterate over the array and for each number store a counter in a hashmap where the key of the map is the number and the value is the counter that tracks the number of occurrences. The first time you encounter a new number (for which there is no key) you'll need insert a new counter. The next time you encounter that same number you simply update the existing counter with a new number.
It also wouldn't be too hard to keep a running 'most matches' number and update it each time you are updating a counter.
public static int numberOfMatches(int[] numbers) {
int mostMatches = 0;
for(int i = 0; i < numbers.length; i++) {
int matches = 0;
int holder = numbers[i];
for(int number : numbers) {
if(number == holder) {
matches++;
}
}
if(matches > mostMatches)
mostMatches = matches;
}
return mostMatches;
}
This accepts an array. It checks the length of the array, and loops for each slot.
For each slot, I create 2 variables. holder grabs the value in the slot, and we increase matches any time there is a match.
Once all possible matches have been found for that slot, it compares the amount of matches found to the highest amount of matches found so far.
for each index in array
HashMap.put(number on index i, occurrences) +=1
check biggest value in the hash map
http://docs.oracle.com/javase/7/docs/api/java/util/HashMap.html#put(K,%20V)
Your countMatches() method is incorrect. Decouple count from the loop variable and check the equality inside the loop, instead of putting it in the loop condition. Change it to something like this:
public static int countMatches(int[] array, int match) throws Exception {
int count = 0;
for(int i=0; i< array.length ; i++){
if(array[i] == match) count++;
}
return count;
}
Also, if I were you, I'd change
for(int index = 0; index < 5; index++) {
to,
for(int index = 0; index < flowers.length; index++) {