Counting number of duplicates in a given array - java

Input: 1,4,2,6,7,5,1,2
Output:2
Counting the number of duplicated numbers in a given array for java. I first sorted the array and then counted duplicates. It's showing me error that variable c is not used and that this method should return value of int.
public class Duplicates
public static void main(String[] args) {
int[]list;
int[]c;
int[] c = new int[list.length];
int temp;
for (int i = 0; i < list.length - 1; i++) {
for (int j = i + 1; j < list; j++) {
if (list[I] > list[j]) {
temp = list[i];
list[i] = list[j];
list[j] = temp;
c = list;
}
}
}
int n = 0;
int counter = 0;
int a = -1;
for (int i = 0; i < c.length; ++i) {
if (c[i] == a) {
++n;
if (n == 1) {
++counter;
if (counter == 1) {
System.out.print(c[i]);
} else {
System.out.print("," + c[i]);
}
}
} else {
a = c[i];
n = 0;
}
}
System.out.println("\nNumber of Duplicated Numbers in array:" + counter);
}
}

It's showing me error that variable c is not used
This should be a warning. So the code should still run correctly even with this is showing.
this method should return value of int
This is a compilation error and since you are not returning any int array at the end of the method, your method's return type should be void. You should change your method signature as below,
public static void c(int[] list)
Otherwise you will need to return an int array at the end of your method.
After fixing your code,
public class Duplicates {
public static void main(String[] args) {
int[] list = new int[]{1, 4, 2, 6, 7, 5, 1, 2};
int temp;
for (int i = 0; i < list.length; ++i) {
for (int j = 1; j < (list.length - i); ++j) {
if (list[j - 1] > list[j]) {
temp = list[j - 1];
list[j - 1] = list[j];
list[j] = temp;
}
}
}
int n = 0, counter = 0;
int previous = -1;
for (int i = 0; i < list.length; ++i) {
if (list[i] == previous) {
++n;
if (n == 1) {
++counter;
if (counter == 1) {
System.out.print(list[i]);
} else {
System.out.print(", " + list[i]);
}
}
} else {
previous = list[i];
n = 0;
}
}
System.out.println("\nNumber of Duplicated Numbers in array: " + counter);
}
}

Related

I try to make the merge sort go from bigger to little but it keep going from little to big

Trying to get it from big to little I'm trying to use the Sort & Search Merge Sort:
import java.util.*;
class MergeSorter {
public static void sort(int[] a) {
if (a.length <= 1) { return; }
int[] first = new int[a.length / 2];
int[] second = new int[a.length - first.length];
for (int i = 0; i < first.length; i++) {
first[i] = a[i];
}
for (int i = 0; i < second.length; i++) {
second[i] = a[first.length + i];
}
sort(first);
sort(second);
merge(first, second, a);
}
private static void merge(int[] first, int[] second, int[] a) {
int iFirst = 0;
int iSecond = 0;
int j = 0;
while (iFirst < first.length && iSecond < second.length) {
if (first[iFirst] < second[iSecond]) {
a[j] = first[iFirst];
iFirst++;
} else {
a[j] = second[iSecond];
iSecond++;
}
j++;
}
while (iFirst < first.length) {
a[j] = first[iFirst];
iFirst++; j++;
}
while (iSecond < second.length) {
a[j] = second[iSecond];
iSecond++; j++;
}
}
}
public class MergeSortDemo888888 {
public static void main(String[] args) {
int [] myAry = { 3, 2, 6, 7 };
System.out.println("myAry is " + Arrays.toString(myAry));
MergeSorter.sort(myAry);
System.out.println("myAry is sorted descendingly using selection sort: "+Arrays.toString(myAry));
}
}
In the first if in the merge function just change this (first[iFirst] < second[iSecond]) into this (first[iFirst] > second[iSecond]).

Two Sum II - Input array is sorted

Leetcode #167 is almost same as #1, but why I cannot only add a if condition?
Q: Given an array of integers that is already sorted in ascending order, find two numbers such that they add up to a specific target number.
The function twoSum should return indices of the two numbers such that they add up to the target, where index1 must be less than index2.
Note:
Your returned answers (both index1 and index2) are not zero-based.
You may assume that each input would have exactly one solution and you may not use the same element twice.
Example:
Input: numbers = [2,7,11,15], target = 9
Output: [1,2]
The sum of 2 and 7 is 9.
Therefore index1 = 1, index2 = 2.
My code:
class Solution {
public int[] twoSum(int[] numbers, int target) {
for (int i = 1; i < numbers.length; i++) {
for (int j = i + 1; j < numbers.length; j++) {
if (numbers[j] == target - numbers[i]) {
if(numbers[i] < numbers[j])
return new int[] { i, j };
}
}
}
return null;
}
}
Why I always return null? where is my mistake? How to fix it?
Because the question says array starts from 1 does not mean array starts from 1 in java.If you want to return i,j as non-zero you should go from 1 to length+1 and then inside the conditions you should check indexes as i-1,j-1 or just start from 0 and return i+1,j+1.
class Solution {
public int[] twoSum(int[] numbers, int target) {
for (int i = 1; i < numbers.length+1; i++) {
for (int j = i + 1; j < numbers.length+1; j++) {
if (numbers[j-1] == target - numbers[i-1]) {
if(numbers[i-1] < numbers[j-1])
return new int[] { i, j };
}
}
}
return null;
}
}
or you can do,
class Solution {
public int[] twoSum(int[] numbers, int target) {
for (int i = 0; i < numbers.length; i++) {
for (int j = i + 1; j < numbers.length; j++) {
if (numbers[j] == target - numbers[i]) {
if(numbers[i] < numbers[j])
return new int[] { i+1, j+1 };
}
}
}
return null;
}
}
https://leetcode.com/problems/two-sum-ii-input-array-is-sorted/
[question]: 167. Two Sum II - Input array is sorted
Using the two-pointer technique:-
class Solution {
public int[] twoSum(int[] numbers, int target) {
if (numbers == null || numbers.length == 0)
return null;
int i = 0;
int j = numbers.length - 1;
while (i < j) {
int x = numbers[i] + numbers[j];
if (x < target) {
++i;
} else if (x > target) {
j--;
} else {
return new int[] { i + 1, j + 1 };
}
}
return null;
}
}
I have modified your code and added code comments on why your previous code has errors. Refer to code below for details.
public class Main {
public static void main(String[] args) {
int target = 9;
int[] numbers = new int[] { 2, 7, 11, 15 };
int[] result = twoSum(numbers, target);
if (result != null) {
System.out
.println("The sum of " + numbers[result[0]] + " and " + numbers[result[1]] + " is " + target + ".");
System.out.println("Therefore index1 = " + (result[0] + 1) + ", index2 = " + (result[1] + 1));
} else {
System.out.println("No Solution found!");
}
}
public static int[] twoSum(int[] numbers, int target) {
for (int i = 0; i < numbers.length; i++) { // array index starts at 0
for (int j = i + 1; j < numbers.length; j++) {
if (numbers[j] + numbers[i] == target) { // add the current numbers
// if (numbers[i] < numbers[j]) // not needed
return new int[] { i, j };
}
}
}
return null;
}
}
Sample input:
numbers = [2, 7, 11, 15];
Sample output:
The sum of 2 and 7 is 9.
Therefore index1 = 1, index2 = 2
You are starting first for-loop with i = 0, what you should do is start it with i = 1.
Working code:
public class Solution
{
public static void main(String[] args)
{
int[] num = {2,7,11,5};
int n = 13;
int[] answer = new int[2];
answer = twoSum(num,n);
if(answer != null)
for(int i=0;i<2;i++)
System.out.printf( answer[i] +" ");
}
public static int[] twoSum(int[] numbers, int target)
{
for (int i = 0; i < numbers.length; i++)
{
for (int j = i + 1; j < numbers.length; j++)
{
if (numbers[j] == target - numbers[i])
{
if(numbers[i] < numbers[j])
return new int[] { i+1, j+1};
}
}
}
return null;
}
}
Note: I have placed an IF before FOR in main() so that if we find no such integers that adds up to give target integer, it'll not throw a NullPointerException.
This is a better solution as it's much faster and covers all test cases as well:
class Solution {
public int[] twoSum(int[] numbers, int target) {
int l = 0, r = numbers.length - 1;
while (numbers[l] + numbers[r] != target) {
if (numbers[l] + numbers[r] > target)
r--;
else
l++;
if (r == l) return new int[]{};
}
return new int[]{l + 1, r + 1};
}
}
public int[] twoSum(int[] nums, int target) {
int start = 0, end = nums.length -1;
while (start < end){
if (nums[start]+ nums[end]== target)
return new int []{start+1, end+1};
if (nums[start]+ nums[end]> target){
end--;}
else if (nums[start]+ nums[end]< target){
start++;
}
}
return null;
}

StackOverflowError eratosthenes sieve implementation

I have tried to implement Eratosthenes sieve in Java, but I have a StackOverflowError like this:
Exception in thread "main" java.lang.StackOverflowError
at com.company.era2.sieve(era2.java:24)
at com.company.era2.sieve(era2.java:24)
at com.company.era2.sieve(era2.java:24)
Seems like its infinite recursion, but algo works fine and fast with n <= 90000
What could I do wrong?
Code:
public class era2 {
public static void print(Object x) {
System.out.println(x);
}
public static List<Integer> sieve(List<Integer> array, int index, int last_crossed){
if (index >= array.size() - 1){
print("Last crossed number : " + last_crossed);
return array;
} else {
for (int i = index + 1; i <= array.size() - 1; i++){
int num = array.get(i);
if (num % array.get(index) == 0) {
array.remove(i);
i--;
last_crossed = num;
}
}
return (sieve(array,index + 1, last_crossed));
}
}
public static void main(String[] args) {
int n = 1000000;
List<Integer> arr = new ArrayList<>();
for (int i = 2; i <= n; i++){
arr.add(i);
}
arr = sieve(arr, 0, 0);
for (int x : arr){
print(x);
}
}
}
If you don't necessarily need to use recursion here is a solution inspired by this wikipedia article
public static List<Integer> sieve(int limit) {
boolean[] array = new boolean[limit - 2];
Arrays.fill(array, true);
int end = (int)Math.sqrt(limit);
for (int i = 2; i <= end; i++) {
if (array[i - 2]) {
int j = i * i;
int k = 0;
while (j < limit) {
array[j - 2] = false;
j = i * i + i * ++k;
}
}
}
List<Integer> result = new ArrayList<>();
for (int l = 2; l < limit; l++) {
if (array[l - 2]) {
result.add(l);
}
}
return result;
}

Removing N duplicates from integer array

problem statement: I have to remove n duplicates from array.
Here is the full problem statement : https://pastebin.com/EJgKUGe3
and my solution is :
public class minion_labour_shift_2ndTry {
static int[] data = {1,2, 2, 3, 3, 3, 4, 5, 5};
public static void main(String[] args) {
Scanner reader = new Scanner(System.in);
int n = reader.nextInt();
data = answer(data, n);
for (int i = 0; i < data.length; i++) {
System.out.print(data[i] + " ");
}
}
public static int[] answer(int[] data, int n) {
if (data.length>99){
System.exit(0);
}
int[] result = new int[99];
ArrayList<Integer> temp = new ArrayList<>();
int counter = 0, count ,maxCount = 0;
for (int i = 0; i < data.length; i++) {
boolean isDistinct = false;
for (int j = 0; j < i; j++) {
if (data[i] == data[j]) {
isDistinct = true;
break;
}
}
if (!isDistinct) {
result[counter++] = data[i];
}
}
for (int i = 0; i < counter; i++) {
count = 0;
for (int j = 0; j < data.length; j++) {
if (result[i] == data[j]) {
count++;
}
}
System.out.println("....... count"+count);
if (maxCount <= count){
maxCount = count;
}
if (count <= n){
temp.add(result[i]);
}
}
if (maxCount-1 < n){
return data;
}
data = new int[temp.size()];
for (int i = 0; i <temp.size() ; i++) {
data[i] = temp.get(i);
}
return data;
}
}
Now, my question is, what I am missing and what should I do to pass all the 10 cases.
Thanks In Advance :)
NB:It will be compiled in java 7 , and Map,hashset or third-party libraries, input/output operations, spawning threads or processes and changes to the execution environment are not allowed.
I misread the requirements initially, this does what is asked:
public static int[] answer(int[] data, int n) {
Map<Integer, Integer> counts = new HashMap<>();
int elementsNeeded = 0;
for (int i = 0; i < data.length; i++) {
Integer currentCount = counts.get(data[i]);
currentCount = currentCount == null ? 1 : ++currentCount;
counts.put(data[i], currentCount);
if (currentCount <= n + 1) {
elementsNeeded += currentCount > n ? -n : 1;
}
}
int[] resultArray = new int[elementsNeeded];
int j = 0;
for (int i = 0; i < data.length; i++) {
if (counts.get(data[i]) <= n) {
resultArray[j++] = data[i];
}
}
return resultArray;
}
...and also your own code, slightly altered:
public static int[] answer2(int[] data, int n) {
if (data.length>99){
System.exit(0);
}
ArrayList<Integer> temp = new ArrayList<>();
int count;
for (int i = 0; i < data.length; i++) {
count = 0;
for (int j = 0; j < data.length; j++) {
if (data[i] == data[j]) {
count++;
}
}
if (count <= n){
temp.add(data[i]);
}
}
data = new int[temp.size()];
for (int i = 0; i <temp.size() ; i++) {
data[i] = temp.get(i);
}
return data;
}
Not going to provide a full solution but suggesting a reworking of the algorithm because it's not clear what you're doing, you never explained your actual thoughts of the algorithm. For example, what are you using isDistinct for?
1) Loop through once and compute the frequency of every number. You can just use an array of length 100 since that's all the data inputs will be. As you loop through, keep track of two things: The total number of entries that occur more than n times, as well as which those numbers are
2) Create a resulting array of the appropriate size (calculated from above) and loop through the list again and fill in the elements that didn't cross the threshold.

Searching for a sum in an array

I have a method which counts how many sums of 3 elements,which are equal to 0, does the array contains. I need help finding the way to stop counting the same triplets in the loop. For instance, 1 + 3 - 4 = 0, but also 3 - 4 +1 = 0.Here is the method:
private static int counter(int A[])
{
int sum;
int e = A.length;
int count = 0;
for (int i=0; i<e; i++)
{
for (int j=i+1; j<e; j++)
{
sum=A[i]+A[j];
if(binarySearch(A,sum))
{
count++;
}
}
}
return count;
edit: I have to use the Binary Search (the array is sorted).
Here is the binarySearch code:
private static boolean binarySearch(int A[],int y)
{
y=-y;
int max = A.length-1;
int min = 0;
int mid;
while (max>=min)
{
mid = (max+min)/2;
if (y==A[mid])
{
return true;
}
if (y<A[mid])
{
max=mid-1;
}
else
{
min=mid+1;
}
}
return false;
You can avoid counting different triplets by making one assumption that we need to look for the triplets (x,y,z) with x < y < z and A[x] + A[y] + A[z] == 0.
So what you need to do is to modify the binarySearch function to return the number of index that greater than y and has A[z] == -(A[x] + A[y])
private static int binarySearch(int A[],int y, int index)
{
y=-y;
int max = A.length-1;
int min = index + 1;
int mid;
int start = A.length;
int end = 0;
while (max>=min)
{
mid = (max+min)/2;
if (y==A[mid])
{
start = Math.min(start, mid);
max = mid - 1;
} else
if (y<A[mid])
{
max=mid-1;
}
else
{
min=mid+1;
}
}
int max = A.length - 1;
int min = index + 1;
while (max>=min)
{
mid = (max+min)/2;
if (y==A[mid])
{
end = Math.max(end, mid);
min= mid + 1;
} else if (y<A[mid])
{
max=mid-1;
}
else
{
min=mid+1;
}
}
if(start <= end)
return end - start + 1;
return 0;
}
So the new function binarySearch will return the total number of index that greater than index and has value equals to y.
So the rest of the job is to count the answer
private static int counter(int A[])
{
int sum;
int e = A.length;
int count = 0;
for (int i=0; i<e; i++)
{
for (int j=i+1; j<e; j++)
{
sum=A[i]+A[j];
count += binarySearch(A,sum, j);
}
}
return count;
}
Notice how I used two binary search to find the starting and the ending index of all values greater than y!
private static int counter(int A[]) {
int e = A.length;
int count = 0;
for (int i = 0; i < e; i++) {
for (int j = 1; (j < e - 1) && (i != j); j++) {
for (int k = 2; (k < e - 2) && (j != k); k++) {
if (A[i] + A[j] + A[k] == 0) {
count++;
}
}
}
}
return count;
}
private static int counter(int ints[]) {
int count = 0;
for (int i = 0; i < ints.length; i++) {
for (int j = 0; j < ints.length; j++) {
if (i == j) {
// cannot sum with itself.
continue;
}
for (int k = 0; k < ints.length; k++) {
if (k == j) {
// cannot sum with itself.
continue;
}
if ((ints[i] + ints[j] + ints[k]) == 0) {
count++;
}
}
}
}
return count;
}
To solve problem with binary search
Your code was almost correct. all you needed to do was just to replace
if (sum == binarySearch(A,sum)) {
with this
if (binarySearch(A,sum)) {
I am assuming that your binarySearch(A, sum) method will return true if it will found sum in A array else false
private static int counter(int A[]) {
int sum;
int e = A.length;
int count = 0;
for (int i=0; i<e; i++) {
for (int j=i+1; j<e; j++) {
sum=A[i]+A[j];
if (binarySearch(A,sum)) {
count++;
}
}
}
return count;
}
Here is my solution assuming the array is sorted and there are no repeated elements, I used the binary search function you provided. Could the input array contain repeated elements? Could you provide some test cases?
In order to not counting the same triplets in the loop, we should have a way of inspecting repeated elements, the main idea that I used here is to have a list of int[] arrays saving the sorted integers of {A[i],A[j],-sum}.Then in each iteration I compare new A[i] and A[j] to the records in the list, thus eliminating repeated ones.
private static int counter(int A[]){
int sum;
int e = A.length;
int count = 0;
List<int[]> elements = new ArrayList<>();
boolean mark = false;
for (int i=0; i<e; i++)
{
for (int j=i+1; j<e; j++)
{
sum=A[i]+A[j];
if (-sum == binarySearch(A,sum)){
int[] sort = {A[i],A[j],-sum};
if(-sum == A[i] || -sum == A[j]){
continue;
}else{
Arrays.sort(sort);
//System.out.println("sort" + sort[0] + " " + sort[1]+ " " + sort[2]);
for (int[] element : elements) {
if((element[0] == sort[0] && element[1] == sort[1]) && element[2] == sort[2])
mark = true;
}
if(mark){
mark = false;
continue;
}else{
count++;
elements.add(sort);
//System.out.println("Else sort" + sort[0] + " " + sort[1]);
}
}
}
}
}
return count;
}
you can use a assisted Array,stored the flag that indicate if the element is used;
Here is the code:
private static int counter(int A[])
{
int sum;
int e = A.length;
int count = 0;
// assisted flag array
List<Boolean> flagList = new ArrayList<Boolean>(e);
for (int k = 0; k < e; k++) {
flagList.add(k, false);// initialization
}
for (int i=0; i<e; i++)
{
for (int j=i+1; j<e; j++)
{
sum=A[i]+A[j];
// if element used, no count
if(binarySearch(A,sum)&& !flagList.get(i)&& !flagList.get(j))
{
count++;
flagList.set(i, true);
flagList.set(j, true);
}
}
}
return count;

Categories

Resources