Algorithm implemented in ruby to add one to a number represented as an array
while new_number > 0 result.push new_number%10 new_number /= 10end
Even though at first glance this loop seems to be O(n)
, it is at least Ω(n²)
.
Since big numbers in Ruby are stored and processed as arrays of binary digits (digits in base 2³²), division by 10
is a costly operation. The exact time complexity depends on the division algorithm Ruby uses, but new_number /= 10
will have to process all of the new_number
's binary digits, so it cannot be faster than O(n)
.
Solution
Note that O(n) should be your worst case scenario (e.g. with [9]*n
).
For [1,2,3]*1000
, the operation can be done in 1 step, since there's no carry and you'd just need to calculate 3+1
.
In your first method, the while
loop seems to be very expensive.
Just using :
(a.join.to_i+1).to_s.chars.map{|i| i.to_i}
is much faster, according to fruity.
Faster solution
if it's acceptable to modify the original array :
class Solution # param a : array of integers # return a array of integers def plusOne(a) a.unshift(0) carry = 1 (a.size-1).downto(0) do |index| if a[index] < 9 a[index] += carry break else a[index] = 0 end end a.shift while a[0] == 0 a endend
It passed the test on www.interviewbit.com, and fruity tells me it's 45 times faster than your second method and 180 times faster than your first one.
def add_1(arr) idx = arr.rindex { |n| n < 9 } return [1].concat([0]*arr.size) if idx.nil? arr.map.with_index do |n,i| case i <=> idx when -1 then n when 0 then n+1 else 0 end endendadd_1 [1, 2, 3] #=> [1, 2, 4] add_1 [1, 2, 9] #=> [1, 3, 0] add_1 [1, 9, 9] #=> [2, 0, 0] add_1 [9, 9, 9] #=> [1, 0, 0, 0]
This could also be written
def add_1(arr) idx = arr.rindex { |n| n < 9 } return [1].concat([0]*arr.size) if idx.nil? (arr[0,idx] << arr[idx]+1).concat([0]*(arr.size-idx-1))end
which may be more efficient.