Algorithm implemented in ruby to add one to a number represented as an array Algorithm implemented in ruby to add one to a number represented as an array ruby ruby

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.