programming-examples/ruby/Arrays/FindTwoRepeatingElem.rb
2019-11-15 12:59:38 +01:00

124 lines
3.1 KiB
Ruby

# Given an array of n+2 elements with elements value lying beween 1 to n.
# All elements occur once except two.Print the two repeating numbers.
#Approach 1: Using sum and product of array (Making two equation)
#Time-complexity: O(n) Auxiliary-space: O(1)
#Caveat: If array is large this can lead to integer overflow.
def find_duplicates(a)
len=a.length
n=len-2
sum_of_series= (n*(n+1))/2 #Sum of series 1 to n
#Find sum and product of array elements
sum=0
product=1
for x in a
sum+=x
product*=x
end
sum-=sum_of_series #sum is a+b now,where a and b are repeating numbers
product/=fact(n) #product is a*b now,where a and b are repeating numbers
temp= Math.sqrt((sum**2)-(4*product)).to_i # temp is a-b
print "#{(sum+d)/2} #{(sum-d)/2}"
end
def fact(x)
return 1 if (x==0 || x==1)
factorial=1
while x>1
factorial*=x
x-=1
end
return factorial
end
find_duplicates([1,2,3,4,5,5,6,7,8,8]) # => 5 8
#Approach 2: Use count array
#Time-complexity: O(n) Auxiliary-space: O(n) {for count array}
def find_duplicates(a)
len=a.length
n=len-2
count=Array.new(n,0) # count has length n
for i in 0...len
if count[a[i]-1]==1
print "#{a[i]} "
else
count[a[i]-1]+=1
end
end
return
end
find_duplicates([1,2,3,4,5,5,6,7,8,8]) # => 5 8
#Approach 3: Using Array Indexing
#Time-complexity: O(n) Auxiliary-space: O(1)
#Caveat: This algorithm modifies the array-elements
def find_duplicates(a)
len=a.length
for i in 0...len
if a[a[i].abs]<0
print "#{a[i].abs} "
else
a[a[i].abs]= -a[a[i].abs]
end
end
return
end
find_duplicates([1,2,3,4,5,5,6,7,8,8]) # => 5 8
#Approach 4: Using bitwise XOR,take xor of all elements and all numbers from 1 to n then,
#find rightmost set bit,divide the range in two sets and take xor of each set, first with xor then with range.
#Time-complexity: O(n) Auxiliary-space: O(1)
def find_duplicates(a)
len=a.length
n=len-2
xor= 0
x,y=0,0 #variables to store duplicates
#xor of all numbers from 1 to n
for i in 1..n
xor^=i
end
#xor of all array elements
for i in 0...len
xor^=a[i]
end
#Rightmost set bit
set_bit_pos= xor & ~(xor-1)
#Divinding array in two sets ,one with set bit at set_bit_pos and other with 0.
for i in 0...len
if (a[i] & set_bit_pos == 0)
x^=a[i] # XOR of first-set(with 0 at set_bit_pos) in array
else
y^=a[i] # XOR of second-set(with 1 at set_bit_pos) in array
end
end
for i in 0..n
if (i & set_bit_pos == 0)
x^=i # XOR of first-set(with 0 at set_bit_pos) in range
else
y^=i # XOR of second-set(with 1 at set_bit_pos) in range
end
end
print "#{x} #{y}"
return
end
find_duplicates([1,2,3,4,5,5,6,7,8,8]) # => 5 8