I'm stuck on this method.
public class Duplicate{
public static boolean extra(int [][] grid)
{
for(int i = 0; i < grid.length; i++)
for(int j = 0; j < grid[i].length-1; j++)
if(grid[i][j] == grid[i][j+1])
{
System.out.println(grid[i][j]);
return true;
}
return false;
}
public static void main(String[] args){
int [][] grades = {{3,5,8,7},
{2,1,11,4},
{13,20,10,6},
{7,0,12,15}
};
System.out.print(extra(grades));
}
}
I want to find if there are any duplicated ints in the array. return true if there is and the int that is duplicated. My method keeps coming out FALSE. what am I doing wrong? Any help would be appreciated. Please and thank you.
All your method is doing is checking if two consecutive elements are equal, which does not tell you anything about duplicates that are not adjacent. One way to do this would be to have a Map<Integer, Integer> that maps the values to their frequencies:
Map<Integer, Integer> map = new HashMap<>();
for (int[] row : grid) {
for (int a : row) {
map.put(a, map.containsKey(a) ? map.get(a) + 1 : 1);
}
}
You can then loop over the entries of this map to find the elements with a frequency greater than or equal to 2.
To rewrite your method so it works:
ArrayList<Integer> comeBefore = new ArrayList<Integer>();
for(int i = 0; i < grid.length; i++) {
for(int j = 0; j < grid[i].length; j++) {
if(comeBefore.contains(grid[i][j])) {
System.out.println(grid[i][j]);
return true;
}
comeBefore.add(grid[i][j]);
}
}
return false;
I don't have time to think about it right now... but maybe a set or such would be a more efficient data structure to use for this. Also this code may not be right... but it's the gist of it; it's untested.
private static boolean extra(int[][] data) {
Set<Integer> set = new HashSet<Integer>();
for (int i = 0; i < data.length; i++) {
for (int j = 0; j < data[i].length; j++) {
if (set.contains(data[i][j])) {
return true;
} else {
set.add(data[i][j]);
}
}
}
return false;
}
You are only comparing adjacent numbers in your loop with this line if(grid[i][j] == grid[i][j+1])
Like arshajii mentioned using a Map will is one way to do this. If you want to keep the co-ordinates of each duplicate then you could extend arshajii's answer to have a Map of Lists like so.
Map<Integer, List<Point>> map = new HashMap<>();
for(int i = 0; i < grid.length; i++)
{
for(int j = 0; j < grid[i].length; j++)
{
int val = grid[i][j];
if(map.containskey(val))
map.put(val, map.get(val).add(new Point(i,j));
else
{
List<Point> li = new ArrayList<>();
li.add(new Point(i,j));
map.put(val, li);
}
}
}
Then to get duplicates you find any key that has a size > 1 and you can get the co-ordinates
for(Integer key : map.ketSet())
{
List<Point> li = map.get(key);
if(li.size() > 1)
{
System.out.println("The value " + key +" was duplicated at the indices: ");
for(Point p : li)
System.out.println(p.x + ", " + p.y);
}
}
But this is probably over the top!
Related
Given the following code:
public static int countSames(Object[] a) {
int count = 0;
for (int i = 0; i < a.length; i++) {
for (int k = 0; k < a.length; k++) {
if (a[i].equals(a[k]) && i != k) {
count += 1;
break; //Preventing from counting duplicate times, is there way to replace this?
}
}
}
return count;
}
I would like to know if there is a solution which doesn't use break statement since I've heard its bad practice.
But without the break this method returns 6 instead of wanted 3 for array {'x', 'x', 'x'}.
If you're trying to find the number of unique elements in the array try using this approach as it has only one loop and hence efficient.
private static int findNUmberOfUnique(String[] array) {
Set<String> set=new HashSet<>();
for(int i=0;i<array.length;i++){
if(!set.contains(array[i])){
set.add(array[i]);
}
}
return set.size();
}
Let me know if I did not understand your requirement clearly.
You can always use a flag instead of break:
public static int countSames(Object[] a) {
int count = 0;
for (int i = 0; i < a.length; i++) {
boolean found = false;
for (int k = 0; k < a.length && !found; k++) {
if (a[i].equals(a[k]) && i != k) {
count += 1;
found = true;
}
}
}
return count;
}
You can use a hashmap to find the same elements in an array and preventing duplicate counting.
class Solution {
public int[] intersection(int[] nums1, int[] nums2) {
HashSet<Integer>hs=new HashSet<Integer>();
for(int i:nums1)
hs.add(i);
HashSet<Integer>hs1=new HashSet<Integer>();
for(int j:nums2){
if(hs.contains(j)){
hs1.add(j);
}
}
int[] res=new int[hs1.size()];
int j=0;
for(int k:hs1)
res[j++]=k;
return res;
}
}
I have to solve an exercise with the following criteria:
Compare two arrays:
int[] a1 = {1, 3, 7, 8, 2, 7, 9, 11};
int[] a2 = {3, 8, 7, 5, 13, 5, 12};
Create a new array int[] with only unique values from the first array. Result should look like this: int[] result = {1,2,9,11};
NOTE: I am not allowed to use ArrayList or Arrays class to solve this task.
I'm working with the following code, but the logic for the population loop is incorrect because it throws an out of bounds exception.
public static int[] removeDups(int[] a1, int[] a2) {
//count the number of duplicate values found in the first array
int dups = 0;
for (int i = 0; i < a1.length; i++) {
for (int j = 0; j < a2.length; j++) {
if (a1[i] == a2[j]) {
dups++;
}
}
}
//to find the size of the new array subtract the counter from the length of the first array
int size = a1.length - dups;
//create the size of the new array
int[] result = new int[size];
//populate the new array with the unique values
for (int i = 0; i < a1.length; i++) {
int count = 0;
for (int j = 0; j < a2.length; j++) {
if (a1[i] != a2[j]) {
count++;
if (count < 2) {
result[i] = a1[i];
}
}
}
}
return result;
}
I would also love how to solve this with potentially one loop (learning purposes).
I offer following soulution.
Iterate over first array, and find out min and max it's value.
Create temporary array with length max-min+1 (you could use max + 1 as a length, but it could follow overhead when you have values e.g. starting from 100k).
Iterate over first array and mark existed values in temorary array.
Iterate over second array and unmark existed values in temporary array.
Place all marked values from temporary array into result array.
Code:
public static int[] getUnique(int[] one, int[] two) {
int min = Integer.MAX_VALUE;
int max = Integer.MIN_VALUE;
for (int i = 0; i < one.length; i++) {
min = one[i] < min ? one[i] : min;
max = one[i] > max ? one[i] : max;
}
int totalUnique = 0;
boolean[] tmp = new boolean[max - min + 1];
for (int i = 0; i < one.length; i++) {
int offs = one[i] - min;
totalUnique += tmp[offs] ? 0 : 1;
tmp[offs] = true;
}
for (int i = 0; i < two.length; i++) {
int offs = two[i] - min;
if (offs < 0 || offs >= tmp.length)
continue;
if (tmp[offs])
totalUnique--;
tmp[offs] = false;
}
int[] res = new int[totalUnique];
for (int i = 0, j = 0; i < tmp.length; i++)
if (tmp[i])
res[j++] = i + min;
return res;
}
For learning purposes, we won't be adding new tools.
Let's follow the same train of thought you had before and just correct the second part:
// populate the new array with the unique values
for (int i = 0; i < a1.length; i++) {
int count = 0;
for (int j = 0; j < a2.length; j++) {
if (a1[i] != a2[j]) {
count++;
if (count < 2) {
result[i] = a1[i];
}
}
}
}
To this:
//populate the new array with the unique values
int position = 0;
for (int i = 0; i < a1.length; i++) {
boolean unique = true;
for (int j = 0; j < a2.length; j++) {
if (a1[i] == a2[j]) {
unique = false;
break;
}
}
if (unique == true) {
result[position] = a1[i];
position++;
}
}
I am assuming the "count" that you implemented was in attempt to prevent false-positive added to your result array (which would go over). When a human determines whether or not an array contains dups, he doesn't do "count", he simply compares the first number with the second array by going down the list and then if he sees a dup (a1[i] == a2[j]), he would say "oh it's not unique" (unique = false) and then stop going through the loop (break). Then he will add the number to the second array (result[i] = a1[i]).
So to combine the two loops as much as possible:
// Create a temp Array to keep the data for the loop
int[] temp = new int[a1.length];
int position = 0;
for (int i = 0; i < a1.length; i++) {
boolean unique = true;
for (int j = 0; j < a2.length; j++) {
if (a1[i] == a2[j]) {
unique = false;
break;
}
}
if (unique == true) {
temp[position] = a1[i];
position++;
}
}
// This part merely copies the temp array of the previous size into the proper sized smaller array
int[] result = new int[position];
for (int k = 0; k < result.length; k++) {
result[k] = temp[k];
}
Making your code work
Your code works fine if you correct the second loop. Look at the modifications I did:
//populate the new array with the unique values
int counter = 0;
for (int i = 0; i < a1.length; i++) {
for (int j = 0; j < a2.length; j++) {
if (a1[i] == a2[j]) {
result[counter] = a1[i];
counter++;
}
}
}
The way I would do it
Now, here is how I would create a method like this without the need to check for the duplicates more than once. Look below:
public static int[] removeDups(int[] a1, int[] a2) {
int[] result = null;
int size = 0;
OUTERMOST: for(int e1: a1) {
for(int e2: a2) {
if(e1 == e2)
continue OUTERMOST;
}
int[] temp = new int[++size];
if(result != null) {
for(int i = 0; i < result.length; i++) {
temp[i] = result[i];
}
}
temp[temp.length - 1] = e1;
result = temp;
}
return result;
}
Instead of creating the result array with a fixed size, it creates a new array with the appropriate size everytime a new duplicate is found. Note that it returns null if a1 is equal a2.
You can make another method to see if an element is contained in a list :
public static boolean contains(int element, int array[]) {
for (int iterator : array) {
if (element == iterator) {
return true;
}
}
return false;
}
Your main method will iterate each element and check if it is contained in the second:
int[] uniqueElements = new int[a1.length];
int index = 0;
for (int it : a1) {
if (!contains(it, a2)) {
uniqueElements[index] = it;
index++;
}
}
Hello I create a 2D array and i want to find the position from the first 2 in the array. And after to add the index in a new ArrayList. But this code doesn't work. Any idea for the problem?
import java.util.ArrayList;
class Test {
public static void main(String[] args) {
ArrayList<Integer> tableau = new ArrayList<Integer>();
int[][] tab = {
{1,1,1,1,1,1,2,1,1,2,1,1,1,2,1,2,1,1,1,1,1},
{1,1,1,1,1,1,1,1,2,1,1,1,1,1,1,1,1,1,1,1,1},
};
for (int i = 0; i < tab.length; i++) {
int j = tab[i].indexOf(2);
for (int k = j ; k < tab[i].length; k++) {
if (tab[i][j] == 2){
tableau.add(j);
}
}
}
for (Integer row : tableau) {
System.out.println("row = "+ Arrays.toString(tableau));
}
}
}
As others have mentioned, regular arrays do not have an indexOf method, meaning that you will get an error when you compile.
However, you can easily create your own method to use as a substitute.
private static int indexOf(int value, int[] array)
{
for (int i=0; i<array.length; i++)
{
if (array[i] == value)
return i;
}
return -1;
}
Then you can just replace this line:
int j = tab[i].indexOf(2);
With this one:
int j = indexOf(2, tab[i]);
i have an array of integers like this one :
A={1,1,4,4,4,1,1}
i want to count the each number once , for this example the awnser is 2 becuase i want to count 1 once and 4 once
i dont want to use sorting methods
i am unable to find a way to solve it using java.
i did this but it gives me 0
public static void main(String args[]) {
int a[] = { 1,1,4,4,4,4,1,1};
System.out.print(new Test4().uniques(a));
}
public int uniques(int[] a) {
int unique = 0;
int tempcount = 0;
for (int i = 0; i < a.length; i++) {
for (int j = 0; j < a.length; j++) {
if (a[i] == a[j]) {
tempcount++;
}
}
if (tempcount <= 2) {
unique=a[i];
}
tempcount = 0;
}
return unique;
}
the purpose of the question is to understand the logic of it but not solving it using ready methods or classes
This one should work. I guess this might be not the most elegant way, but it is pretty straightforward and uses only simple arrays. Method returns number of digits from array, but without counting duplicates - and this I believe is your goal.
public int uniques(int[] a) {
int tempArray[] = new int[a.length];
boolean duplicate = false;
int index = 0;
int digitsAdded = 0;
for (int i = 0; i < a.length; i++) {
for (int j = 0; j < tempArray.length; j++) {
if (a[i] == tempArray[j]) {
duplicate = true;
}
}
if(!duplicate) {
tempArray[index] = a[i];
index++;
digitsAdded++;
}
duplicate = false;
}
//this loop is needed if you have '0' in your input array - when creating temp
//array it is filled with 0s and then any 0 in input is treated as a duplicate
//again - not most elegant solution, maybe I will find better later...
for(int i = 0; i < a.length; i++) {
if(a[i] == 0) {
digitsAdded++;
break;
}
}
return digitsAdded;
}
Okay first of all in your solution you are returning the int unique, that you are setting as the value that is unique a[i]. So it would only return 1 or 4 in your example.
Next, about an actual solution. You need to check if you have already seen that number. What you need to check is that for every number in the array is only appears in front of your position and not before. You can do this using this code below.
public int uniques(int[] a) {
int unique = 1;
boolean seen = false;
for (int i = 1; i < a.length; i++) {
for (int j = 0; j < i; j++) {
if (a[i] == a[j]) {
seen = true;
}
}
if (!seen) {
unique++;
}
seen = false;
}
return unique;
}
In this code you are iterating over the number you have seen and comparing to the number you are checking (a[i]). You know that for it to be unique you cant have seen it before.
I see two possible solutions:
using set
public int unique(int[] a) {
Set<Integer> set = new HashSet<>();
for (int i : a) {
set.add(i);
}
return set.size();
}
using quick sort
public int unique(int[] a) {
Arrays.sort(a);
int cnt = 1;
int example = a[0];
for (int i = 1; i < a.length; i++) {
if (example != a[i]) {
cnt++;
example = a[i];
}
}
return cnt;
}
My performance tests say that second solution is faster ~ 30%.
if restricted to only arrays, consider trying this:
Lets Take a temporary array of the same size of orignal array, where we store each unique letter and suppose a is your orignal array,
int[] tempArray= new int[a.length];
int tempArraycounter = 0;
bool isUnique = true;
for (int i = 0; i < a.length; i++)
{
isUnique = true;
for (int j = 0; j < tempArray.length; j++)
{
if(tempArray[j] == a[i])
isUnique = false;
}
if(isUnique)
{
tempArray[tempArraycounter] = a[i];
tempArraycounter++;
isUnique = false;
}
}
now tempArraycounter will be your answer ;)
Try Following code:
int test[]={1,1,4,4,4,1,1};
Set<Integer> set=new LinkedHashSet<Integer>();
for(int i=0;i<test.length;i++){
set.add(test[i]);
}
System.out.println(set);
Output :
[1, 4]
At the end set would contain unique integers.
I have a 2D Array and I would like to find an easier way to manipulate my code so that it will find if there is a duplicate in the column and easier way then what I have below:
for (int i=0; i < array.length; i++) {
for (int j=0; j < array.length; j++) {
for (int k=1; k < array.length; k++){
if (array[j+k][i] == array[j][i]) {
if (array[j][i] != 0) {
return true;
}
}
}
}
}
return false;
EDIT: KINDLY POINTED OUT THE ABOVE ^^ WON'T WORK EITHER AS IT WILL THROW AN OUT OF BOUNDS EXCEPTION
This way has too many loops and I am sure there must be an easier way to find duplicates rather than going through this massive looping process.
This is for a square 2D array, ie. an array with rows = columns.
If so, how can this new way work - and how can I manipulate it to work to find duplicate values in the rows as well.
Thanks for the help.
you can use HashSet to store all already encountered elements. should be something like this:
static boolean noDupes(int[][] array) {
for (int i=0; i < array.length; i++) {
HashSet<Integer> set = new HashSet<Integer>();
for (int j=0; j < array.length; j++) {
if (set.contains(array[j][i])) return false;
set.add(array[j][i]);
}
}
return true;
}
this solution is O(length^2) = O(n) where n is the matrix total size. I think it is ideal in terms of big O, because you need to check all elements.
int[][] array = new int[3][5];
for (int i = 0; i < array.length; i++) // array initialization
for (int j = 0; j < array[i].length; j++ )
array[i][j] = i*j;
Map<Integer, Set<Point>> map = new HashMap<Integer, Set<Point>>();
for (int i = 0; i < array.length; i++)
for (int j = 0; j < array[i].length; j++)
if (map.containsKey(array[i][j]))
map.get(array[i][j]).add(new Point(i, j));
else
{
Set<Point> set = new HashSet<Point>();
set.add(new Point(i, j));
map.put(array[i][j], set);
}
for (Map.Entry<Integer, Set<Point>> entry : map.entrySet())
if (entry.getValue().size() > 1)
{
System.out.println("value = " + entry.getKey());
for (Point p : entry.getValue())
System.out.println("coordinates = " + p);
System.out.println();
}
The output is as expected:
value = 0
coordinates = java.awt.Point[x=0,y=3]
coordinates = java.awt.Point[x=0,y=0]
coordinates = java.awt.Point[x=2,y=0]
coordinates = java.awt.Point[x=0,y=4]
coordinates = java.awt.Point[x=0,y=2]
coordinates = java.awt.Point[x=1,y=0]
coordinates = java.awt.Point[x=0,y=1]
value = 2
coordinates = java.awt.Point[x=1,y=2]
coordinates = java.awt.Point[x=2,y=1]
value = 4
coordinates = java.awt.Point[x=2,y=2]
coordinates = java.awt.Point[x=1,y=4]
Finding the Duplicate Elements in a given Matrix - JAVA
static void findDuplicates(String[][] matrix) {
HashSet<String> uniqInp = new HashSet<String>();
HashSet<String> allDup = new HashSet<String>();
System.out.println("***** DUPLICATE ELEMENTS *****");
for(int row=0;row<matrix.length;row++)
{
for(int col=0;col<matrix[0].length;col++)
{
if(uniqInp.add(matrix[row][col]))
//If not duplicate it will add
continue;
else {
// If Duplicate element found, it will come here
if(allDup.add(matrix[row][col]))
System.out.print(matrix[row][col]+" ");
}
}
}
}