Find "Missing" Integer in a Java Array - java

Given an array A[] of length n, find a "missing" number k such that:
k is not in A
0<=k<=n
I've seen similar questions asked where the A[] contains numbers 1 to n with one number missing, but in this question, A[] can contain any numbers. I need a solution in O(n) time. For example,
A = {1,2,3} -> 0
A = {0,1,2} -> 3
A = {2,7,4,1,6,0,5,-3} -> 3,8
I've gotten as far as checking if 0 or n are in the array, and if not, return 0 or n, but I cannot seem to think of any other solution. This problem seems considerably more difficult given the fact that A can contain any numbers and not necessarily numbers 1 to n or something like that.

Linearly iterate over the array and "cross out" every number you encounter. Then iterate of that listed of crossed out numbers again and see which one is missing.
public static int getMissingNumber(int[] A)
{
int n = A.length;
boolean[] numbersUsed = new boolean[n + 1]; //Because the definition says 0 <= k <= n, so k = n is also possible.
for(int k = 0; k < n; k++)
{
if(A[k] <= n && A[k] >= 0) //No negative numbers!
numbersUsed[A[k]] = true;
}
for(int k = 0; k <= n; k++)
{
if(numbersUsed[k] == false)
return k;
}
return -1; //nothing found
}
Complexity is 2*n because of the two for loops, giving overall complexity O(n).

Simple approach:
initialize a set with all the values you need. (In your case number 0 to n)
iterate over your arry and remove the number from the set
at the end the set is giving you the missing entries.

If you know that exactly one number is missing, there is a simple solution using xor.
static int missing(int[] arr) {
int result = 0;
for (int i = 0; i < arr.length; i++)
result ^= (i + 1) ^ arr[i];
return result;
}
If there may be more than one number missing you can return a Set like this:
static Set<Integer> missing(int[] arr) {
Set<Integer> set = new HashSet<>();
for (int i = 0; i <= arr.length; i++)
set.add(i);
for (int a : arr)
set.remove(a);
return set;
}

Here is a solution that utilizes one loop. That's if we choose to ignore what Arrays.sort does
import java.util.Arrays;
class Solution {
public int solution(int[] A) {
Arrays.sort(A);
int min = 1;
for (int i = 0; i < A.length; i++){
if(A[i]== min){
min++;
}
}
min = ( min <= 0 ) ? 1:min;
return min;
}
}

class Missing{
public static void main(String[] args) {
int arr[]={1,2,4,5,6,7,9};
System.out.println(missingNumberArray(arr));
}
public static int missingNumberArray(int [] a) {
int result=0;
for(int i=0;i<a.length-1;i++){
if(a[i+1]-a[i]!=1){
result=a[i]+1;
}
}
return result;
}
}
//output:missing element is:3
// missing element is:8

Related

rotate the elements of the given array k times to the right

I have made this code to rotate an array by k times. In this when I'm adding i=0 , it is showing an "ArrayOutOfBounds" exception, and when I'm changing the value of i by 1, it is showing wrong output. Why is it showing this exception? And is there any way I could correct this code?
public void rotate(int[] nums, int k)
{ int j=0, temp=0;
for(j=0;j<k;j++)
{
for(int i=0;i<nums.length;i++)
{
temp=nums[i-1];
nums[i-1]=nums[i];
nums[i]=temp;
}
}
}
}
At i=0 you are trying to access nums[i-1] = num[-1] which is an invalid position and hence an ArrayOutOfBound exception is thrown.
So, the modified version would be:
for (j=0; j<k; j++)
{
for (int i=1;i<nums.length;i++)
{
temp=nums[i-1];
nums[i-1]=nums[i];
nums[i]=temp;
}
}
But the above will rotate the array by k times towards the left not right as you are shifting the elements towards the left. So, to get the right rotation you need to shift the elements from the end of the array. Like:
for (j=0; j<k; j++)
{
for (int i=nums.length-1; 0<i; i--)
{
// shifting towards the right
temp=nums[i-1];
nums[i-1]=nums[i];
nums[i]=temp;
}
}
Edit (from comments above): If i is 0, you're trying to get an index of -1 which will raise an ArrayOutOfBounds exception. If i starts from 1, then you're not dealing with the first number.
Here's the function you can use to rotate integers to the right:
public void rotate(int[] nums, int k) {
int arrLen = nums.length;
// If the number of times you want to rotate is bigger than the size of the array, get the minimum number of rotations to get the same result.
while (k > n) {
k = k - arrLen;
}
k = arrLen - k;
k = k % arrLen;
int i, m, n, temp;
int g_c_d = gcd(k, arrLen);
// Move the value in the i-th index
for (i = 0; i < g_c_d; i++) {
temp = arr[i];
m = i;
while (true) {
n = m + k;
if (n >= arrLen) {
n = n - arrLen;
}
if (n == i) {
break;
}
arr[m] = arr[n];
m = n;
}
arr[m] = temp;
}
}
// Find the greatest common divisor of two numbers, a and b
public void gcd(int a, int b) {
if (b == 0) {
return a;
} else {
return gcd(b, a % b);
}
}
Let me briefly explain what it does. This is one of the most known algorithms: juggling. You divide the array into the n number of sets where n denotes the greatest common divisor of the length of the array and the number of times you want to rotate. Then, you move the numbers within sets.
This might be the most efficient in terms of time (as its time complexity is O(n)).
A better solution would be taking a copy of the given array with the values '0' then looping through the given array to obtain a new_index.
Formula for the New_index for the Clock-wise rotating array:
for(int i=0;i<nums.length;i++){
int new_index = (old_index+k)%(a.length)
copy[new_index] = a[old_index]
}
Now the entire function code would be:
public static void rotate(int[] a, int k)
{
int n = a.length;
int[] copy = new int[n];
// fill the values with zeroes
for(int i=0;i<n;i++){
copy[i]=0;
}
// rotate the array
for(int i=0;i<n;i++){
int new_index = (i+k)%n;
copy[new_index] = a[i];
}
// Now that the array is copied, copy the elements to the original array. Because they asked to rotate the given array.
for(int i=0;i<n;i++){
a[i]=copy[i];
}
}
function solution(arr, k) {
if(k == 0) return arr;
if(arr.length == k) return arr;
if(arr !== undefined && arr !== null){
let counter = k > arr.length ? k % arr.length : k;
let rotArray = [];
rotArray = arr.slice(arr.length - counter, arr.length).concat(arr.slice(0,arr.length - counter))
return rotArray;
}
return arr;
}

Given two sorted lists (or arrays) and a number k, create an algorithm to fetch the least k numbers of the two lists

Need to find the first 3 smallest number in given two sorted array. I supposed that two array should merge into one first and sort it in order to fetch the first 3 smallest number. Can anyone help me with the merge and sort part or provide some advice, any help will appreciate.
This is where i reached now, I only can get the smallest number ( not first 3, just one).
public class MergeandSort {
public static void main(String[] args) {
int[] set1 = {1,2,6,9,18};
int[] set2 = {2,3,7,10,21,30};
int smallest = set1[0];
int smallests = set2[0];
for(int i=0; i < set1.length; i++){
if(set1[i] < smallest)
smallest = set1[i];
}
for(int k=0; k < set2.length; k++){
if(set2[k] < smallests)
smallests = set2[k];
}
System.out.println("Smallest Number in Set 1 is : " + smallest);
System.out.println("Smallest Number in Set 2 is : " + smallests);
}
}
The arrays are already sorted, so you don't have to iterate over the entire arrays to find the 3 smallest numbers.
You just have to start iterating over both arrays at the same time (i.e. in the same loop).
In each iteration you compare the current two elements of the two arrays (starting at the 2 elements at the 0 index) and take the smaller of them
Then you advance the index of the array from which you took the smallest number.
Once you reach 3 elements (after 3 iterations), you break out of the loop.
Here's some pseudo code to get you started:
int i = 0;
int j = 0;
int c = 0;
int[] lowest3 = new int[3];
while (true) {
find the smaller of set1[i] and set2[j] and put it in lowest3[c]
if set1[i] is smaller, increment i
otherwise increment j
increment c
if (c==3) // you are done
break;
}
the lowest3 array now contains the 3 lowest numbers of both arrays
Of course you can swap 3 with any k. You just have to make sure that i is always smaller than set1.length and j is always smaller than set2.length.
If the arrays are already sorted, just implement the merging technique of merge sort with the limitation in while condition that it should run only k times (in this case 3), but dont forget to check that size of sets are less than k or not!
int k = 0,i = 0,j = 0;
while (k<3 && k<set1.length && k<set2.length )
{
if (set1[i] <= set2[j])
{
final_set[k] = set1[i];
i++;
}
else
{
final_set[k] = set2[j];
j++;
}
k++;
}
while (k<3 && k<set1.length) {
final_set[k]=set1[i];
k++;
i++;
}
while (k<3 && k<set2.length) {
final_set[k]=set1[j];
k++;
j++;
}
public class MergeandSort {
public static void main(String[] args) {
int[] set1 = {1,2,6,9,18};
int[] set2 = {2,3,7,10,21,30};
int[] sorted = new int[k];
int smallest = set1[0];
int smallests = set2[0];
int i = 0, j = 0, c = 0;
while(i < set1.length && j < set2.length && c < k){
if (set1[i] < set2[j])
sorted[c++] = arr1[i++];
else
sorted[c++] = arr2[j++];
while (i < set1.length && c < k)
sorted[c++] = arr1[i++];
while (j < set2.length && c < k)
sorted[c++] = arr2[j++];
System.out.println(sorted);
}
}
where k is the count of sorted numbers you want
That would not work as:
Array1 = {1,3,5}
Array2 = {2,3,4}
Correct solution: {1,2,3}
Output of your solution: {1,3,4}

I want to find the 10 first Amicable Pair with only use of arrays, loops and conditions but I'm very new to java and programming in general

I think I know how to enter the sum of division into cell on the array but stuck on how to compare between the arrays and print the 10 pairs.
My code so far:
public static void main(String[] args) {
int sum1=0,sum2=0;
int[] arr1=new int[67000];
int[] arr2=new int[67000];
for(int i =0;i<=10;i++){
for(int j =1;j<arr1.length;j++){
for(int k =0;k<j;k++){
if(j%k==0){
sum1+=k;
}
}arr1[j]=sum1;
}
for(int j =1;j<arr2.length;j++){
for(int k =0;k<j;k++){
if(j%k==0){
sum2+=k;
}
}arr2[j]=sum2;
}
}
}
You are calculating the same values in both the arrays. Just create the array once.
for (int j = 2; j < arr.length; j++) {
int sum = 0;
for (int k = 1; k < j; k++) {
if (j % k == 0) {
sum += k;
}
}
arr[j] = sum;
}
Now, here, arr[n] is the sum of the proper divisors of a number n.
We can compare the pairs by looping through arr as:
int cnt = 0, first = 2;
while(cnt < 10) {
int second = arr[first];
if (second >= arr.length) {
continue;
}
if (second > first) {
if (first == arr[second]) {
System.out.printf("%d %d\n", first, second);
cnt++;
}
}
first++;
if (first >= arr.length) {
break;
}
}
The first check is to avoid overrunning the array index, the second > first check is to make sure we only look forward and not rediscover a pair twice.
And then the main check is first == arr[second] which is what amicable numbers are. What it's saying is that if the sum of divisors of the second number which in fact is the sum of divisors of the first number is the first number itself, then the numbers are amicable pairs.
Side Note:
The program could probably be written in other better ways.
For example when finding the sum, looping up to the square root of the number in question is enough as the divisors mirror each other.

Reversing araylist of integers manually

public static ArrayList<Integer> reverse (ArrayList<Integer> n) {
ArrayList<Integer> result = new ArrayList<Integer>();
for(int i = 0; i < n.size(); i++) {
int j = n.size() - i - 1;
result.add(i, n.get(j));
}
return result;
}
but if i enter an array 1,2,3,4,5,6,7,8,9,10
the result is 10,9,8,7,6,5,4,3,2,10
Where is my mistake?
Actually, what you have there works fine. But you can simplify your for-loop by iterating 'backwards':
for(int i = n.size() - 1 ; i >= 0 ; i--)
result.add(n.get(i));
Oh, and one more thing I should mention. When you declare the list result, you might want to specify its capacity, since you know what it will be. i.e.:
ArrayList<Integer> result = new ArrayList<Integer>(n.size());
Uses n.size() / 2 swaps (the fewest possible) and runs in linear time.
public static ArrayList<Integer> reverse (ArrayList<Integer> n)
{
for (int i = 0, j = n.size() - 1, t; i <= size / 2; ++i, --j)
{
t = n.get(i);
n.set(i, n.get(j));
n.set(j, t);
}
return n;
}
Collections.reverse(arrayList);
In case you still want to go for a manual one,
public ArrayList<Integer> reverse(ArrayList<Integer> arrayList) {
ArrayList<Integer> result = (ArrayList<Integer>)list.clone();
for (int start=0,end=result.size()-1;start<end;start++,end--) {
swap(result,start,end) ;
}
return result;
}
public void swap(ArrayList<Integer> temp, int front, int back) {
Integer i = temp.set(front,temp.get(back)) ;
temp.set(back, i) ;
}
It doesn't work for lists with even numbers of items

how to optimize query on how to count number of array elements that don't have values between them

I want to write a method that when supplied an array of ints will do the following. For each pair of array elements it will combine them and put them into a list of an inner class objects. Then it will compare each element in the array and check if it will fit between each pair values. (i.e. I have an array 0, 2, 4 it will make for example pair (0,4) and then it will check that value 2 is indeed between 0 and 4 and so for pair (4,0). When pair (0, 2) is evaluated it won't find anything and therefore counter will increase (and so for pair (2, 0)). I have constructed the following code to evaluate number of values that indeed will fit in pairs and I hoped then to get the total number of pairs that match my need by extracting it from the total number of pairs. Now I want to optimize this query (in case I have very big arrays with thousands of members and very big or negative integers e.g. 1,000,000,000 or - 2,000,000,000). Please let me know how to do that. Mainly please focus on optimization issues thank you.
import java.util.*;
import java.util.Map;
import java.lang.*;
public class Prac1 {
public int count(int[] A){
int k = 0;
class PTemp{
int first = 0;
int second = 0;
public PTemp(int first, int second){
this.first = first;
this.second = second;
}
}
List<PTemp> r = new ArrayList<PTemp>();
int z = 0;
for (int i = 0; i < A.length; i++) {
for (int j = i+1; j < A.length; j++) {
r.add(new PTemp(A[i], A[j]));
r.add(new PTemp(A[j], A[i]));
z = z + 2;
System.out.println("["+A[i] +","+A[j]+"]");
System.out.println("["+A[j] +","+A[i]+"]");
}
}
Iterator<PTemp> ir = r.iterator();
while (ir.hasNext()){
PTemp p = ir.next();
label1:
for (int i = 0; i < A.length-1; i++){
if (((p.first < A[i]) && (A[i] < p.second)) || ((p.first > A[i]) && (A[i] > p.second))){
k = k + 1;
break label1;
}
}
}
System.out.println(z);
k = z - k;
return k;
}
public int c(int[] A) {
int z = (A.length - 1) * 2;
return z;
}
public static void main(String[] args){
int[] A = {0, 2, 2, 6, 5, 5};
Prac1 pr = new Prac1();
System.out.println(pr.count(A));
System.out.println(pr.c(A));
}
}
Without loss of generality, we can consider the array to be sorted. Assuming all numbers in the array are distinct, the pairs without elements in between are the pairs formed by neighbours. There are (array.length - 1) * 2 such pairs, i.e. you could simply do:
public int count(int[] A) {
return (A.length - 1) * 2;
}
If the array may contain duplicates, you should specify how they are to be counted.
Sort the array. Make a single pass over the array, identifying groups of equal elements. For each such group, multiply the number of elements in the group, the number of smaller elements, and the number of larger elements. Add that to a running count.
public int count(int[] A) {
int i = 0, k = 0, j = 0;
Arrays.sort(A); // you need to import java.util.Arrays
while(i < A.length) {
for(j = i+1; j < A.length && A[j] == A[i]; j++);
k += (j - i) * i * (A.length - j);
i = j;
}
return k;
}

Categories