Related
Given a sorted array A of size N, delete all the duplicates elements from A.
Note: Don't use set or HashMap to solve the problem.
example:
Input:
N = 5
Array = {2, 2, 2, 2, 2}
Output:
2
Explanation: After removing all the duplicates
only one instance of 2 will remain.
I have tried the below code. Please tell me what's wrong with the code?
int remove_duplicate(int arr[],int N){
// code here
int index=0;
for(int i=1;i<N;i++){
if(arr[i]!=arr[i-1]){
arr[index]=arr[i-1];
index++;
}
}
return index+1;
}
You could replace some duplicate elements and set the length at the end.
This approach mutates the array.
const
remove_duplicate = array => {
let j = 0;
for (let i = 0; i < array.length; i++) {
if (array[j - 1] !== array[i]) array[j++] = array[i];
}
array.length = j;
return array;
};
console.log(...remove_duplicate([2, 2, 2]));
console.log(...remove_duplicate([1, 1, 2, 2, 3, 4, 5, 5]));
Overkill using binary tree
BinaryTree binaryTree = new BinaryTree();
for (int i = 0; i < n; i++){
//add or insert function need to check that the key isn't in the stracture
binaryTree.Add(arr[i]);
}
binaryTree.TraverseInOrder(binaryTree.Root);
You need to implement some of the classes.
Check this example:
c-binary-search-tree-implementation
For more on Inorder output for binaryTree:
binary-tree-from-inorder-traversal
Look here: https://www.geeksforgeeks.org/duplicates-array-using-o1-extra-space-set-2/
// Java program to print all elements that
// appear more than once.
import java.util.*;
class GFG {
// function to find repeating elements
static void printRepeating(int arr[], int n)
{
// First check all the values that are
// present in an array then go to that
// values as indexes and increment by
// the size of array
for (int i = 0; i < n; i++)
{
int index = arr[i] % n;
arr[index] += n;
}
// Now check which value exists more
// than once by dividing with the size
// of array
for (int i = 0; i < n; i++)
{
if ((arr[i] / n) >= 2)
System.out.println(i + " ");
}
}
// Driver code
public static void main(String args[])
{
int arr[] = { 1, 6, 3, 1, 3, 6, 6 };
int arr_size = arr.length;
System.out.println("The repeating elements are: ");
// Function call
printRepeating(arr, arr_size);
}
}
Try this:
int remove_duplicate(int arr[],int N){
int index=0;
for(int i=1;i<N;i++){
if(arr[i]!=arr[index]){ //change index
index++; //swapt next line
arr[index]=arr[i];
}
}
return index+1;
}
you can check my answer here - and it works perfectly
https://stackoverflow.com/a/32931932/3052125
Here is the main logic to remove the duplicates - arr is the sorted array provided to you with duplicate elements -
// Logic for removing the duplicate elements
int compare = 0;
arr[compare] = arr[0];
for (int i = 1; i < size; i++) {
if (arr[compare] != arr[i]) {
compare++;
arr[compare] = arr[i];
}
}
Given a sorted array A of size N, delete all the duplicates elements from A
Well, that implies returning an array with duplicates deleted.
int[] v = { 1, 1, 1, 2, 2, 2, 2,3 };
v = remove_duplicates(v);
System.out.println(Arrays.toString(v));
prints
[1, 2, 3]
The method. This works by copying the unique values toward the front of the passed array. So this does alter that array.
public static int[] remove_duplicates(int[] v) {
int current = 0;
for (int i = 0; i < v.length; i++) {
if (v[i] != v[current]) {
v[++current] = v[i];
}
}
// Now return the front portion of the array that contains the distinct
// values. You could also just create a new array and copy the elements
// using a loop.
return Arrays.copyOf(v, current+1);
}
This question already has answers here:
How to count duplicate elements in ArrayList?
(13 answers)
Closed 4 years ago.
I must not modify the contents of the array, like using Array.sort().
Expected return of this code is 6, because there are three duplicates of the value 1, one duplicate of the value 2, and two duplicates of the value 4. but mine is showing 10. I know the reason why it is 10: it's counting the duplicates multiple times.
How can I make this code check duplicate integer only once?
private int count = 0;
public void run() {
int[] a = {1, 4, 2, 4, 7, 1, 1, 9, 2, 3, 4, 1};
println(countDuplicates(a));
}
private int countDuplicates(int[] a) {
for (int i = 0; i < a.length; i++) {
for (int j = i + 1; j < a.length; j++) {
if (a[i] == a[j]) {
count++;
}
}
}
return count;
}
One option would be to take the current size minus the size with duplicates removed:
Set<Integer> set = new HashSet<>();
for (int i=0; i < a.length; ++i) {
set.add(a[i]);
}
int numDuplicates = a.length - set.size();
There is probably a sleek way to populate a set of Integer from an array of primitive int using streams in Java 8.
Here you go with simple to understand logic for leaners
public static void main(String[] args) throws IOException {
int []a ={1, 4, 2, 4, 7, 1, 1, 9, 2, 3, 4, 1};
Map<Integer, Integer> occurances = new HashMap<>();
for(int i = 0; i < a.length; i++) {
//Check the is already occurred if not then add occurrence as 1
if (!occurances.containsKey(a[i])) {
occurances.put(a[i], 1);
}
// Second occurrences for a number
else {
occurances.put(a[i], occurances.get(a[i]) + 1);
}
}
System.out.println(occurances);
System.out.println("Total Numbers: "+a.length);
System.out.println("Duplicate count is "+ (a.length - occurances.size()));
}
Sort the array in-place.
Run through the array once, and count how many times current value is equal to previous value.
(Assuming you are allowed to use a library method to sort the array)
private static int countDuplicates(final int[] a)
{
int count = 0;
Arrays.sort(a); // sort array, you can use any way for it
for (int i = 0; i < a.length - 1; i++)
{
if (a[i] == a[i + 1]) // check only next element
{
count++;
}
}
return count; // return 6
}
I am currently practicing algorithm development with Java and have recently really got stuck on a particular problem. I have been challenged to develop two different algorithm.
My task is to solve the selection problem. the selection problem determines the kth largest number in a group of N numbers.
I have successfully implemented the first algorithm. I read the N numbers into an array, sort the array in decreasing order by some simple algorithm, and then return the element in position k.
Note: k = N / 2
Here is the working code
public int selectionAlgorithmOne() {
int[] intArray = new int[]{1, 7, 9, 8, 2, 3, 5, 4, 6, 10};
//I sort the array of size N in decreasing order
bubbleSortDecreasingOrder(intArray);
//{10, 9, 8, 7, 6, 5, 4, 3, 2, 1}
//I obtain the value of k
int k = intArray.length / 2;
//I print the result
System.out.println(intArray[k]);
}
The value that is printed in "5" which is correct! However, the second algorithm is a bit trickier.
Read the first k elements into an array and sort them in decreasing order. Next, each remaining element is read one by one. As a new element arrives, it is ignored if it is smaller than the kth element in the array. Otherwise, it is placed in its correct spot in the array, bumping one element out of the array. When the algorithm ends, the element in the kth position is returned as the answer.
Unfortunately my second algorithm does not work. It returns the value "3" which is wrong. It should be returning the same value of "5" as the first algorithm but in a more efficient.
I have been stuck for a few days now and I am really struggling to find the solution. Hopefully I have given the problem enough context, let me know if I can provide any more information. Thanks in advance.
Here is the non-working code
public int selectionAlgorithmTwo() {
int[] intArray = new int[]{1, 7, 9, 8, 2, 3, 5, 4, 6, 10};
int arrayLength = intArray.length;
int k = arrayLength / 2;
int[] firstHalf = new int[k];
//I read the first half of the elements into an array
for (int i = 0; i < k; i++) {
firstHalf[i] = intArray[i];
}
//I then sort the first half of the elements in decreasing order
bubbleSort(firstHalf);
for(int i = k; i < arrayLength; i++) {
int val = intArray[i];
//If the new element to insert is >= the kth largest
if (val > firstHalf[k - 1]) {
int pos = 0;
for(; pos < k; pos++) {
if(val > firstHalf[pos]) {
break; //I break once I have the correct position located
}
//I make the swap
for (int j = k - 1; j > pos; j--)
firstHalf[j] = firstHalf[j - 1];
firstHalf[pos] = val;
}
}
}
return firstHalf[k - 1];
}
First of all, "the element in position k" isn't the kth element, it's the k+1 th element. Indeed 5 is the sixth element of the sorted array.
So, if you want to return the element in position k, you need an array of k+1 element.
Therefore I added the firstHalfLen variable.
If you use an array of k element, you'll never get 5 as answer.
In the block if (val > firstHalf[k]), in order to find the correct index, I preferred a while loop
while ((pos < firstHalfLen) && (val <= firstHalf[pos])) {
pos++;
}
Then the swap:
for (int j = k; j > pos; j--) {
firstHalf[j] = firstHalf[j - 1];
}
Code:
int[] intArray = new int[] { 1, 7, 9, 8, 2, 3, 5, 4, 6, 10 };
int arrayLength = intArray.length;
int k = arrayLength / 2;
int firstHalfLen = k + 1;
int[] firstHalf = new int[firstHalfLen];
// I read the first half of the elements into an array
for (int i = 0; i < firstHalfLen; i++) {
firstHalf[i] = intArray[i];
}
//I then sort the first half of the elements in decreasing order
bubbleSort(firstHalf);
for (int i = firstHalfLen; i < arrayLength; i++) {
int val = intArray[i];
// If the new element to insert is >= the kth largest
if (val > firstHalf[k]) {
int pos = 0;
// find index
while ((pos < firstHalfLen) && (val <= firstHalf[pos])) {
pos++;
}
// Swap
for (int j = k; j > pos; j--) {
firstHalf[j] = firstHalf[j - 1];
}
firstHalf[pos] = val;
}
}
return firstHalf[k];
You are comparing values from the unsorted part to values of the sorted part, starting low, i.e. at small values. The probability that the value is larger than the first sorted value is quite high. More interesting would be a value which is smaller. According to your algorithm, the smaller unsorted value should be inserted into the small sorted values, at the position where it replaces a higher value, not a smaller one.
So
if(val > firstHalf[pos])
should be
if(val < firstHalf[pos])
Try this code:
public int sortTest() {
int[] intArray = new int[]{1, 7, 9, 8, 2, 3, 5, 4, 6, 10};
int arrayLength = intArray.length;
int k = arrayLength / 2;
int[] firstHalf = new int[k];
//I read the first half of the elements into an array
for (int i = 0; i < k; i++) {
firstHalf[i] = intArray[i];
}
//I then sort the first half of the elements in decreasing order
bubbleSort(firstHalf);
for(int i = k; i < arrayLength; i++) {
int val = intArray[i];
//If the new element to insert is >= the kth largest
if (val > firstHalf[k - 1]) {
int pos = 0;
for(; pos < k; pos++) {
if(val > firstHalf[pos]) {
break; //I break once I have the correct position located
}
}
//I make the swap
for (int j = k - 1; j > pos; j--)
firstHalf[j] = firstHalf[j - 1];
firstHalf[pos] = val;
}
}
return firstHalf[k - 1];
}
The error in your code is that, after you found the correct position and break, you leave the for loop without the swap procedure.
Also note that this code return 6, not 5, because you returned the k-1 th value.
I'm currently working on a problem that asks me to find the millionth lexicographic permutation of 0,1,2,3,4,5,6,7,8,9. I thought of a very crude solution at first glance that had a complexity of around O(n^3)
public static String permute(char[] a){
ArrayList<String> array = new ArrayList<String>();
int counter = 1;
for (int i = 0; i < a.length; i++){
array[counter] += a[i];
for (int j = 0; j < i; j++){
array[counter] += a[j];
for(int k = a.length; k > i; k--){
array[counter] += a[k];}counter++;}
}
}
The code may not be perfect but the idea is that a single digit is selected and then moves to the end of an array. The second array creates the numbers behind the selected digit and the third array creates numbers after it. This seems like a terrible algorithm and i remembered a past algorithm that's like this.
public static HashSet<String> Permute(String toPermute) {
HashSet<String> set = new HashSet<String>();
if (toPermute.length() <= 1 )
set.add(toPermute);
else {
for (int i = 0; i < toPermute.length(); i++ )
for (String s: Permute(toPermute.substring(0,i)+ toPermute.substring(i+1)))
{
set.add(toPermute.substring(i,i+1)+s);}
}
return set;
}
}
The problem is that this algorithm uses unordered sets and I have no idea about how it can become ordered enough for me to find the millionth permutation. I also do not know the complexity other than the fact it could be O(n^2) because it calls itself n times and then unstacks.
A couple of things in general about your code above:
You should implement to interfaces and not concrete classes I.e. List<String> array = .... Similarly with your Set.
Array's start at index 0, you are starting your counter at index 1.
Finally to answer your question there is a brute force way and a more elegant way that uses some principles in math. Have a look at this site which explains the approaches.
It seems to me (1) which permutation is the millionth depends absolutely on the order you use, and (2) permutations of this sort are ripe problems for recursion. I would write this as a recursive program and increment the count for each iteration. [was that your question? I didn't really see a question...]
Here is a solution that is more efficient:
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class P24 {
static final int digits[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
static List<Integer> remainedDigits = new ArrayList(Arrays.asList(0, 1, 2, 3, 4, 5, 6, 7, 8, 9));
static final int factorials[] = new int[digits.length + 1];
static final int N = 1000_000;
static int low = -1;
static int lowIndex = -1;
static int highIndex = -1;
public static void main(String args[]) {
populateFactorials(digits.length);
validateN(N);
identifyMargins();
int n = N; // it will be changed
int fixedDigits = digits.length - highIndex;
String result = "";
for (int i = 0; i < fixedDigits; i++) {
result += remainedDigits.get(0);
remainedDigits.remove(0);
}
for (int i = fixedDigits; i < digits.length; i++) {
int pos = 0;
int firstDigit = remainedDigits.get(pos);
low = factorials[lowIndex];
while (n - low > 0) {
pos++;
n -= low;
}
lowIndex--;
result += remainedDigits.get(pos);
remainedDigits.remove(pos);
}
System.out.println(result);
}
private static void validateN(int n) {
if (n < 0 || n > factorials[factorials.length - 1]) {
System.out.println("The input number is not valid");
System.exit(0);
}
}
private static void identifyMargins() {
for (int i = 0; i < factorials.length - 1; i++) {
if (factorials[i] <= N && N < factorials[i + 1]) {
lowIndex = i;
highIndex = i + 1;
}
}
}
private static void populateFactorials(int max) {
for (int i = 0; i <= max; i++) {
factorials[i] = fact(i);
}
}
private static int fact(int x) {
if (x == 0 || x == 1) {
return 1;
}
int p = 1;
for (int i = 2; i <= x; i++) {
p *= i;
}
return p;
}
}
Time: 305 microseconds.
Explanation:
Because the total number of permutations for {a1, ..., an} is n!, I decided that I need a factorials array. I stored in it: {0!, ..., 10!}.
I identified where is the number placed in this sequence, and for our case (N = 1000000) it is between 9! and 10!. If it was lower than 9! I add a padding of fixedDigits digits taken from the remainedDigits array.
Because the number is bigger than 9!, I count how many times I can extract 9! from the number and the result helps me to obtain the first digit. Then, I have a similar approach for 8!, 7!, etc.
The above explanation is based on the following simple observation. If we have a set {a1,...,ai,...,an} and we fix a1, ..., ai, we can obtain (n-i)! different strings.
Notice that if you use:
static List<Integer> remainedDigits = Arrays.asList(0, 1, 2, 3, 4, 5, 6, 7, 8, 9);
you cannot remove elements from the list.
`
This is my first post, hope it complies with posting guidelines of the site.
First of all a generic thanks to all the community: reading you from some months and learned a lot :o)
Premise: I'm a first years student of IT.
Here's the question: I'm looking for an efficient way to count the number of unique pairs (numbers that appear exactly twice) in a given positive int array (that's all I know), e.g. if:
int[] arr = {1,4,7,1,5,7,4,1,5};
the number of unique pairs in arr is 3 (4,5,7).
I have some difficulties in... evaluating the efficiency of my proposals let's say.
Here's the first code I did:
int numCouples( int[] v ) {
int res = 0;
int count = 0;
for (int i = 0 ; i < v.length; i++){
count = 0;
for (int j = 0; j < v.length; j++){
if (i != j && v[i] == v[j]){
count++;
}
}
if (count == 1){
res++;
}
}
return res/2;
}
This shoudn't be good cause it checks the whole given array as many times as the number of elements in the given array... correct me if I'm wrong.
This is my second code:
int numCouples( int[] v) {
int n = 0;
int res = 0;
for (int i = 0; i < v.length; i++){
if (v[i] > n){
n = v[i];
}
}
int[] a = new int [n];
for (int i = 0; i < v.length; i++){
a[v[i]-1]++;
}
for (int i = 0; i < a.length; i++){
if (a[i] == 2){
res++;
}
}
return res;
}
I guess this should be better than the first one since it checks only 2 times the given array and 1 time the n array, when n is the max value of the given array. May be not so good if n is quite big I guess...
Well, 2 questions:
am I understanding good how to "measure" the efficiency of the code?
there's a better way to count the number of unique pairs in a given array?
EDIT:
Damn I've just posted and I'm already swamped by answers! Thanks! I'll study each one with care, for the time being I say I don't get those involving HashMap: out of my knowledge yet (hence thanks again for the insight:o) )
public static void main(String[] args) {
int[] arr = { 1, 4, 7, 1, 5, 7, 4, 1, 5 };
Map<Integer, Integer> map = new HashMap<Integer, Integer>();
for (int i = 0; i < arr.length; i++) {
Integer count = map.get(arr[i]);
if (count == null)
map.put(arr[i], 1);
else
map.put(arr[i], count + 1);
}
int uniqueCount = 0;
for (Integer i : map.values())
if (i == 2)
uniqueCount++;
System.out.println(uniqueCount);
}
Well, here's another answer to your's 2 questions:
am I understanding good how to "measure" the efficiency of the code?
There are various ways to measure efficiency of the code. First of all, people distinguish between memory efficiency and time efficiency. The usual way to count all these values is to know, how efficient are the building blocks of your algorithm. Have a look at the wiki.
For instance, sorting using quicksort would need n*log(n) operations. Iterating through the array would need just n operations, where n is number of elements in the input.
there's a better way to count the number of unique pairs in a given array?
Here's another solution for you. The complixity of this one would be: O(n*log(n)+n), where O(...) is Big O notation.
import java.util.Arrays;
public class Ctest {
public static void main(String[] args) {
int[] a = new int[] { 1, 4, 7, 1, 7, 4, 1, 5, 5, 8 };
System.out.println("RES: " + uniquePairs(a));
}
public static int uniquePairs(int[] a) {
Arrays.sort(a);
// now we have: [1, 1, 1, 4, 4, 5, 5, 7, 7]
int res = 0;
int len = a.length;
int i = 0;
while (i < len) {
// take first number
int num = a[i];
int c = 1;
i++;
// count all duplicates
while(i < len && a[i] == num) {
c++;
i++;
}
System.out.println("Number: " + num + "\tCount: "+c);
// if we spotted number just 2 times, increment result
if (c == 2) {
res++;
}
}
return res;
}
}
public static void main(String[] args) {
int[] arr = {1,4,7,1,7,4,1,5};
Map<Integer, Integer> counts = new HashMap<Integer,Integer>();
int count = 0;
for(Integer num:arr){
Integer entry = counts.get(num);
if(entry == null){
counts.put(num, 1);
}else if(counts.get(num) == 1){
count++;
counts.put(num, counts.get(num) + 1);
}
}
System.out.println(count);
}
int [] a = new int [] {1, 4, 7, 1, 7, 4, 1, 5, 1, 1, 1, 1, 1, 1};
Arrays.sort (a);
int res = 0;
for (int l = a.length, i = 0; i < l - 1; i++)
{
int v = a [i];
int j = i + 1;
while (j < l && a [j] == v) j += 1;
if (j == i + 2) res += 1;
i = j - 1;
}
return res;
you can use HashMap for easy grouping. here is my code.
int[] arr = {1,1,1,1,1,1,4,7,1,7,4,1,5};
HashMap<Integer,Integer> asd = new HashMap<Integer, Integer>();
for(int i=0;i<arr.length;i++)
{
if(asd.get(arr[i]) == null)
{
asd.put(arr[i], 1);
}
else
{
asd.put(arr[i], asd.get(arr[i])+1);
}
}
//print out
for(int key:asd.keySet())
{
//get pair
int temp = asd.get(key)/2;
System.out.println(key+" have : "+temp+" pair");
}
added for checking the unique pair, you can delete the print out one
//unique pair
for(int key:asd.keySet())
{
if(asd.get(key) == 2)
{
System.out.println(key+" are a unique pair");
}
}
after some time another solution, which should work great.
public getCouplesCount(int [] arr) {
int i = 0, i2;
int len = arr.length;
int num = 0;
int curr;
int lastchecked = -1;
while (i < len-1) {
curr = arr[i];
i2 = i + 1;
while (i2 < len) {
if (curr == arr[i2] && arr[i2] != lastchecked) {
num++; // add 1 to number of pairs
lastchecked = curr;
i2++; // iterate to next
} else if (arr[i2] == lastchecked) {
// more than twice - swap last and update counter
if (curr == lastchecked) {
num--;
}
// swap with last
arr[i2] = arr[len-1];
len--;
} else {
i2++;
}
i++;
}
return num;
}
i am not shure if it works, but it is more effective than sorting the array first, or using hashmaps....
A Java8 parallel streamy version which uses a ConcurrentHashMap
int[] arr = {1,4,7,1,5,7,4,1,5};
Map<Integer,Long> map=Arrays.stream(arr).parallel().boxed().collect(Collectors.groupingBy(Function.identity(),
ConcurrentHashMap::new,Collectors.counting()));
map.values().removeIf(v->v!=2);
System.out.println(map.keySet().size());
#include <bits/stdc++.h>
using namespace std;
int main()
{
ios_base::sync_with_stdio(false);
cin.tie(NULL);
int arr[9] = {1,4,7,1,5,7,4,1,5}; // given array
int length=9; // this should be given
int count=0;
map<int,int> m;
for(int i=0;i<length;i++)
m[arr[i]]++;
cout<<"List of unique pairs : ";
for(auto it=m.begin();it!=m.end();it++)
if(it->second==2)
{
count++;
cout<<it->first<<" ";
}
cout<<"\nCount of unique pairs(appears exactly twice) : "<<count;
return 0;
}
OUTPUT :
List of unique pairs : 4 5 7
Count of unique pairs(appears exactly twice) : 3
Time Complexity : O(N) where N is the number of elements in array
Space Complexity : O(N) total no. of unique elements in array always <=N
var sampleArray = ['A','B','C','D','e','f','g'];
var count = 0;
for(var i=0; i<=sampleArray.length; i++) {
for(var j=i+1; j<sampleArray.length; j++) {
count++;
console.log(sampleArray[i] , sampleArray[j]);
}
}
console.log(count);
This is the simple way I tried.