missing numbers - c

Given an array of size n. It contains numbers in the range 1 to n. Each number is present at
least once except for 2 numbers. Find the missing numbers.
eg. an array of size 5
elements are suppose 3,1,4,4,3
one approach is
static int k;
for(i=1;i<=n;i++)
{
for(j=0;j<n;j++)
{
if(i==a[j])
break;
}
if(j==n)
{
k++;
printf("missing element is", a[j]);
}
if(k==2)
break;}
another solution can be..
for(i=0;i

Let me First explain the concept:
You know that sum of natural numbers 1....n is
(n*(n+1))/2.Also you know the sum of square of sum of first n natural numbers 1,2....n is n*(n+1)*(2n+1)/6.Thus you could solve the above problem in O(n) time using above concept.
Also if space complexity is not of much consideration you could use count based approach which requires O(n) time and space complexity.
For more detailed solution visit Find the two repeating elements in a given array

I like the "use array elements as indexes" method from Algorithmist's link.
Method 5 (Use array elements as index)
Thanks to Manish K. Aasawat for suggesting this method.
traverse the list for i= 1st to n+2 elements
{
check for sign of A[abs(A[i])] ;
if positive then
make it negative by A[abs(A[i])]=-A[abs(A[i])];
else // i.e., A[abs(A[i])] is negative
this element (ith element of list) is a repetition
}
The only difference is that here it would be traversing 1 to n.
Notice that this is a single-pass solution that uses no extra space (besides storing i)!
Footnote:
Technically it "steals" some extra space -- essentially it is the counter array solution, but instead of allocating its own array of ints, it uses the sign bits of the original array as counters.

Use qsort() to sort the array, then loop over it once to find the missing values. Average O(n*log(n)) time because of the sort, and minimal constant additional storage.

I haven't checked or run this code, but you should get the idea.
int print_missing(int *arr, size_t length) {
int *new_arr = calloc(sizeof(int) * length);
int i;
for(i = 0; i < length; i++) {
new_arr[arr[i]] = 1;
}
for(i = 0; i < length; i++) {
if(!new_arr[i]) {
printf("Number %i is missing\n", i);
}
}
free(new_arr);
return 0;
}
Runtime should be O(2n). Correct me if I'm wrong.

It is unclear why the naive approach (you could use a bitfield or an array) of marking the items you have seen isn't just fine. O(2n) CPU, O(n/8) storage.

If you are free to choose the language, then use python's sets.
numbers = [3,1,4,4,3]
print set (range (1 , len (numbers) + 1) ) - set (numbers)
Yields the output
set([2, 5])

Here you go. C# solution:
static IEnumerable<int> FindMissingValuesInRange( int[] numbers )
{
HashSet<int> values = new HashSet<int>( numbers ) ;
for( int value = 1 ; value <= numbers.Length ; ++value )
{
if ( !values.Contains(value) ) yield return value ;
}
}

I see a number of problems with your code. First off, j==n will never happen, and that doesn't give us the missing number. You should also initialize k to 0 before you attempt to increment it. I wrote an algorithm similar to yours, but it works correctly. However, it is not any faster than you expected yours to be:
int k = 0;
int n = 5;
bool found = false;
int a[] = { 3, 1, 4, 4, 3 };
for(int i = 1; i <= n; i++)
{
for(int j = 0; j < n; j++)
{
if(a[j] == i)
{
found = true;
break;
}
}
if(!found)
{
printf("missing element is %d\n", i);
k++;
if(k==2)
break;
}
else
found = false;
}
H2H

using a support array you can archeive O(n)
int support[n];
// this loop here fills the support array with the
// number of a[i]'s occurences
for(int i = 0; i < n; i++)
support[a[i]] += 1;
// now look which are missing (or duplicates, or whatever)
for(int i = 0; i < n; i++)
if(support[i] == 0) printf("%d is missing", i);

**
for(i=0; i < n;i++)
{
while((a[i]!=i+1)&&(a[i]!=a[a[i]-1])
{
swap(a[i],a[a[i]-1]);
}
for(i=0;i< n;i++)
{
if(a[i]!=i+1)
printf("%d is missing",i+1); }
this takes o(n) time and o(1) space
========================================**

We can use the following code to find duplicate and missing values:
int size = 8;
int arr[] = {1, 2, 3, 5, 1, 3};
int result[] = new int[size];
for(int i =0; i < arr.length; i++)
{
if(result[arr[i]-1] == 1)
{
System.out.println("repeating: " + (arr[i]));
}
result[arr[i]-1]++;
}
for(int i =0; i < result.length; i++)
{
if(result[i] == 0)
{
System.out.println("missing: " + (i+1));
}
}

This is an interview question: Missing Numbers.
condition 1 : The array must not contain any duplicates.
The complete solution is :
public class Solution5 {
public static void main(String[] args) {
int a[] = { 1,8,6,7,10};
Arrays.sort(a);
List<Integer> list = new ArrayList<>();
int start = a[0];
for (int i = 0; i < a.length; i++) {
int ch = a[i];
if(start == ch) {
start++;
}else {
list.add(start);
start++;
//must do this
i--;
}
}//for
System.out.println(list);
}//main
}

Related

Find the most frequent elements in an array of Integers

I have to find all of the elements which have the maximum frequency. For example, if array a={1,2,3,1,2,4}, I have to print as 1, also 2. My code prints only 2. How to print the second one?
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define n 6
int main(){
int a[n]={1,2,3,1,2,4};
int counter=0,mostFreq=-1,maxcnt=0;
for(int i=0;i<n;i++){
for(int j=i+1;j<n;j++){
if(a[i]==a[j]){
counter++;
}
}
if(counter>maxcnt){
maxcnt=counter;
mostFreq=a[i];
}
}
printf("The most frequent element is: %d",mostFreq);
}
How to print the second one?
The goal it not only to print a potential 2nd one, but all the all of the elements which have the maximum frequency.
OP already has code that determines the maximum frequency. Let us build on that. Save it as int target = mostFreq;.
Instead of printing mostFreq, a simple (still O(n*n)) approach would perform the same 2-nested for() loops again. Replace this 2nd:
if(counter>maxcnt){
maxcnt=counter;
mostFreq=a[i];
}
With:
if(counter == target){
; // TBD code: print the a[i] and counter.
}
For large n, a more efficient approach would sort a[] (research qsort()). Then walk the sorted a[] twice, first time finding the maximum frequency and the 2nd time printing values that match this frequency.
This is O(n* log n) in time and O(n) in memory (if a copy of the original array needed to preserve the original). If also works well with negative values or if we change the type of a[] from int to long long, double, etc.
The standard student solution to such problems would be this:
Make a second array called frequency, of the same size as the maximum value occurring in your data.
Init this array to zero.
Each time you encounter a value in the data, use that value as an index to access the frequency array, then increment the corresponding frequency by 1. For example freq[value]++;.
When done, search through the frequency array for the largest number(s). Optionally, you could sort it.
We can (potentially) save some effort in an approach with unsorted data by creating an array of boolean flags to determine whether we need to count an element at all.
For the array {1, 2, 3, 1, 2, 4} we do have nested for loops, so O(n) complexity, but we can avoid the inner loop entirely for repeated numbers.
#include <stdio.h>
#include <stdbool.h>
int main(void) {
int arr[] = {1, 2, 3, 1, 2, 4};
size_t arr_size = sizeof(arr) / sizeof(*arr);
bool checked[arr_size];
for (size_t i = 0; i < arr_size; i++) checked[i] = false;
unsigned int counts[arr_size];
for (size_t i = 0; i < arr_size; i++) counts[i] = 0;
for (size_t i = 0; i < arr_size; i++) {
if (!checked[i]) {
checked[i] = true;
counts[i]++;
for (size_t j = i+1; j < arr_size; j++) {
if (arr[i] == arr[j]) {
checked[j] = true;
counts[i]++;
}
}
}
}
unsigned int max = 0;
for (size_t i = 0; i < arr_size; i++) {
if (counts[i] > max) max = counts[i];
}
for (size_t i = 0; i < arr_size; i++) {
if (counts[i] == max)
printf("%d\n", arr[i]);
}
return 0;
}

How to find the number of elements in the array that are bigger than all elements after it?

I have a function that takes a one-dimensional array of N positive integers and returns the number of elements that are larger than all the next. The problem is exist a function to do it that in a better time? My code is the following:
int count(int *p, int n) {
int i, j;
int countNo = 0;
int flag = 0;
for(i = 0; i < n; i++) {
flag = 1;
for(j = i + 1; j < n; j++) {
if(p[i] <= p[j]) {
flag = 0;
break;
}
}
if(flag) {
countNo++;
}
}
return countNo;
}
My solution is O(n^2). Can it be done better?
You can solve this problem in linear time(O(n) time). Note that the last number in the array will always be a valid number that fits the problem definition. So the function will always output a value that will be greater than equal to 1.
For any other number in the array to be a valid number it must be greater than or equal to the greatest number that is after that number in the array.
So iterate over the array from right to left keeping track of the greatest number found till now and increment the counter if current number is greater than or equal to the greatest found till now.
Working code
int count2(int *p, int n) {
int max = -1000; //this variable represents negative infinity.
int cnt = 0;
int i;
for(i = n-1; i >=0; i--) {
if(p[i] >= max){
cnt++;
}
if(p[i] > max){
max = p[i];
}
}
return cnt;
}
Time complexity : O(n)
Space complexity : O(1)
It can be done in O(n).
int count(int *p, int n) {
int i, currentMax;
int countNo = 0;
currentMax = p[n-1];
for(i = n-1; i >= 0; i--) {
if(currentMax < p[i])
{
countNo ++;
currentMax = p[i];
}
}
return countNo;
}
Create an auxillary array aux:
aux[i] = max{arr[i+1], ... ,arr[n-1] }
It can be done in linear time by scanning the array from right to left.
Now, you only need the number of elements such that arr[i] > aux[i]
This is done in O(n).
Walk backwards trough the array, and keep track of the current maximum. Whenever you find a new maximum, that element is larger than the elements following.
Yes, it can be done in O(N) time. I'll give you an approach on how to go about it. If I understand your question correctly, you want the number of elements that are larger than all the elements that come next in the array provided the order is maintained.
So:
Let len = length of array x
{...,x[i],x[i+1]...x[len-1]}
We want the count of all elements x[i] such that x[i]> x[i+1]
and so on till x[len-1]
Start traversing the array from the end i.e. at i = len -1 and keep track of the largest element that you've encountered.
It could be something like this:
max = x[len-1] //A sentinel max
//Start a loop from i = len-1 to i = 0;
if(x[i] > max)
max = x[i] //Update max as you encounter elements
//Now consider a situation when we are in the middle of the array at some i = j
{...,x[j],....x[len-1]}
//Right now we have a value of max which is the largest of elements from i=j+1 to len-1
So when you encounter an x[j] that is larger than max, you've essentially found an element that's larger than all the elements next. You could just have a counter and increment it when that happens.
Pseudocode to show the flow of algorithm:
counter = 0
i = length of array x - 1
max = x[i]
i = i-1
while(i>=0){
if(x[i] > max){
max = x[i] //update max
counter++ //update counter
}
i--
}
So ultimately counter will have the number of elements you require.
Hope I was able to explain you how to go about this. Coding this should be a fun exercise as a starting point.

Rearrange an array so that arr[i] becomes arr[arr[i]] with O(1) extra space

The task is to rearrange an array so that arr[i] becomes arr[arr[i]] with O(1) extra space.
Example:
2 1 3 5 4 0
becomes:
3 1 5 0 4 2
I can think of an O(n²) solution. An O(n) solution was presented here:
Increase every array element arr[i] by (arr[arr[i]] % n)*n.
Divide every element by n.
But this is very limited as it will cause buffer overflow.
Can anyone come up with an improvement upon this?
If the values in the array are all positive (or all negative), one way to avoid overflow could be to run the permutation cycles and use the integer sign to mark visited indexes. (Alternatively, if the array length is smaller than 2^(number of bits for one array element - 1), rather than use the sign, we could shift all the values one bit to the left and use the first bit to mark visited indexes.) This algorithm results in both less iterations and less modifications of the original array values during run-time than the algorithm you are asking to improve.
JSFiddle: http://jsfiddle.net/alhambra1/ar6X6/
JavaScript code:
function rearrange(arr){
var visited = 0,tmp,indexes,zeroTo
function cycle(startIx){
tmp = {start: startIx, value: arr[startIx]}
indexes = {from: arr[startIx], to: startIx}
while (indexes.from != tmp.start){
if (arr[indexes.from] == 0)
zeroTo = indexes.to
if (indexes.to == visited){
visited++
arr[indexes.to] = arr[indexes.from]
} else {
arr[indexes.to] = -arr[indexes.from]
}
indexes.to = indexes.from
if (indexes.from != tmp.start)
indexes.from = arr[indexes.from]
}
if (indexes.to == visited){
visited++
arr[indexes.to] = tmp.value
} else {
arr[indexes.to] = -tmp.value
}
}
while (visited < arr.length - 1){
cycle(visited)
while (arr[visited] < 0 || visited == zeroTo){
arr[visited] = -arr[visited]
visited++
}
}
return arr
}
//Traverse the array till the end.
//For every index increment the element by array[array[index] % n]. To get //the ith element find the modulo with n, i.e array[index]%n.
//Again traverse to end
//Print the ith element after dividing the ith element by n, i.e. array[i]/n
class Rearrange
{
void rearrange(int arr[], int n)
{
for (int i = 0; i < n; i++)
arr[i] += (arr[arr[i]] % n) * n;
for (int i = 0; i < n; i++)
arr[i] /= n;
}
void printArr(int arr[], int n)
{
for (int i = 0; i < n; i++)
System.out.print(arr[i] + " ");
System.out.println("");
}
public static void main(String[] args)
{
Rearrange rearrange = new Rearrange();
int arr[] = {6, 4, 9, 2, 5, 7};
int n = arr.length;
System.out.println("Given Array is :");
rearrange.printArr(arr, n);
rearrange.rearrange(arr, n);
System.out.println("Modified Array is :");
rearrange.printArr(arr, n);
}
}

Finding an element repeating n times in 2n size array. Will this solution work?

I have an array which has 2n elements where n elements are same and remaining n elements are all different. There are lot of other complex algorithms to solve this problem.
Question: Does this approach give the same result or I am wrong somewhere?
#include<stdio.h>
main()
{
int arr[10],i,res,count=0;
printf("Enter the array elements:\t");
for(i=0;i<10;i++)
scanf("%d",&arr[i]);
for(i=0;i<8;i++)
{
if(arr[i]==arr[i+1] || arr[i]==arr[i+2])
{
res=arr[i];
break;
}
else if(arr[i+1]==arr[i+2])
{
res=arr[i+1];
break;
}
}
for(i=0;i<10;i++)
if(arr[i]==res)
count++;
if(count==5)
printf("true, no. repeated is:\t%d",res);
else printf("false");
return 0;
}
In addition to failing for the trivial 2 element case, it also fails for 4 elements in this case:
a b c a
I think the easiest way to solve this problem is to solve the majority element problem on a[1] ... a[2*N-1], and if no majority is found, then it must be a[0] if a solution exists at all.
One solution to the majority element problem is to scan through the array counting up a counter whenever the majority candidate element is encountered, and counting down the counter when a number different from the candidate is encountered. When the counter is 0, the next element is automatically considered the new candidate.
If the counter is positive at the end of the scan, the candidate is checked with another scan over the array. If the counter is 0, or the second scan fails, there is no majority element.
int majority (int a[], int sz) {
int i, count1 = 0, count2 = 0;
int candidate = -1;
for (i = 0; i < sz; ++i) {
if (count1 == 0) candidate = i;
count1 += ((a[candidate] == a[i]) ? 1 : -1);
}
if (count1 > 0) {
for (i = 0; i < sz; ++i)
count2 += (a[candidate] == a[i]);
}
if (count2 <= sz/2) candidate = -1;
return candidate;
}
Your algorithm will fail when the array has only 2 elements. It does not handle trivial case

maximum contiguous sum in a circular buffer

I have a program to determine the largest contiguous sum in an array, but want to extend it to work with circular arrays. Is there an easier way to do that than doubling the single array and calling my function to find the largest sum over all n-length arrays in the 2n length array?
See the following link :
It solves a problem using Kadane Algorithem.
http://www.geeksforgeeks.org/maximum-contiguous-circular-sum/
I think the solution by #spinning_plate is wrong. Ca you please test it for the given cases.
int arr[] = {-3, 6, 2, 1, 7, -8, 13, 0};
Your approach returns 21.
Actual solution can be start from 6th index(i.e. 13 value) .. and end to 4th index(i.e. 7 value). Since array is circular we can take continuous series from 6th index to 7th index and from 0th index to 4th index.
The actual answer for the above case is : 26
Well, you don't have to actually double the array. You can just emulate it by indexing your existing array modulo n, or by just iterating over it twice. Depending on the size of your array and cache behavior, this should be at most a factor of two slower than the algorithm for the noncircular array.
For the given problem,
We will apply kadane algorithm and we will also find the subset which will have maximum negative value.If the maximum negative value is removed that will give the sum of the remaining array in circular order.If that sum is greater than maximum sum then maximum sum will be sum in circular order.
Complexity for the algorithm is O(n).
Eg:- arr[i]={10,-3,-4,7,6,5,-4,-1}
Ans: max_sum=7+6+5+(-4)+(-1)+10
Removed_set={-3,-4}
int find_maxsum(int arr[],int n)
{
int i=0;
int total=0;
int maxa=0;
int mini=0;
int min_sum=0;
int max_sum=0;
while(i<n)
{
maxa=maxa+arr[i];
total=total+arr[i];
mini=mini+arr[i];
if(maxa>max_sum)
max_sum=maxa;
if(mini<min_sum)
min_sum=mini;
if(maxa<0)
maxa=0;
if(mini>=0)
mini=0;
}
if(total-min_sum>max_sum)
max_sum=total-min_sum;
return max_sum;
}
I assume you are using the O(n) algorithm that continues adding to the sum, keeping track of the maximum, only restarting if you sum to a negative number. The only thing you need to do to capture the case of circular arrays is to apply the same principle to the circular aspect. When you reach the end of the array in the original algorithm, keep looping around to the start until you go below the maximum or hit the beginning of the current range (I think this is impossible, though, because if the solution was the full array, we sould have seen this on the first pass), in which case you're done.
max_start=0; max_end =0; maxv = 0; sum 0;
for i in range(arr):
sum+= arr[i];
if sum<0:
sum=0; max_start =i;
if maxv<sum:
maxv=sum; max_end = i;
#seocnd pass
for i in range(max_start):
sum+= arr[i];
if sum<0:
break;
if maxv<sum:
maxv=sum;max_end = i;
Correct code based on nikhil's idea: elements of the minimum sum sub-array cannot appear in the final wrapping-or-not maximum sum sub-array.
public int maxSum(int[] arr) {
if (arr.length == 0) return 0;
int sum = 0;
int min = Integer.MAX_VALUE;
int eix = 0;
for (int i = 0; i < arr.length; i++) {
sum = sum + arr[i] < arr[i] ? sum + arr[i] : arr[i];
if (sum < min) {
min = sum;
eix = i;
}
}
int max = 0;
sum = 0;
for (int i = eix; i < arr.length + eix; i++) {
int ix = i < arr.length ? i : i - arr.length;
sum = sum + arr[ix] > arr[ix] ? sum + arr[ix] : arr[ix];
max = max > sum ? max : sum;
}
return max;
}
This code returns the correct answer even if all numbers are negative e.g., {-1, -2, -3}.
will return -1;
public static int maxSubarraySumCircular(int[] A) {
int maxSum = Arrays.stream(A).max().getAsInt();
if (maxSum < 0)
return maxSum;
int maxKadane = KadaneAlgorithm(A);
int maxWrap = 0;
for (int i = 0; i < A.length; i++) {
maxWrap += A[i];
A[i] = -A[i];
}
maxWrap = maxWrap + KadaneAlgorithm(A);
return maxWrap > maxKadane ? maxWrap : maxKadane;
}
private static int KadaneAlgorithm(int[] A) {
int maxSoFar = 0;
int maxEndingHere = 0;
for (int i = 0; i < A.length ; i++) {
maxEndingHere = maxEndingHere + A[i];
if (maxEndingHere < 0 )
maxEndingHere = 0;
if(maxSoFar < maxEndingHere)
maxSoFar = maxEndingHere;
}
return maxSoFar;
}

Resources