Brute force
For query , number of ops is
.
Time: , space:
.
class Solution:
def minOperations(self, nums: List[int], queries: List[int]) -> List[int]:
n, m = len(nums), len(queries)
num_ops = [0]*m
for i, q in enumerate(queries):
num_ops[i] = sum( abs(q-x) for x in nums )
return num_ops
Sort and search
If , we can remove the
. Then, number of ops is
. So, for each
, we can find the number of ops in
time. Similarly, if
, the number of ops,
, can be found in
time.
The two cases are mixed up in nums. We can sort nums to separate out the cases.

We can binary-search in nums to find where should have been in sorted order and from that we can find the region where
and the region where
. We need to efficiently find the prefix or suffix sums, so we precompute cumulative sums.
Time: , space:
.
class Solution:
def find_insert_index(self, x, nums) -> int:
lo, hi = 0, len(nums)-1
while lo <= hi:
mid = (lo+hi) // 2
if nums[mid] == x:
return mid
if nums[mid] < x:
lo = mid+1
else:
hi = mid-1
return lo
def find_cumulative_sum(self, nums) -> List[int]:
cumsum = [nums[0]] + [0] * (len(nums)-1)
for i, x in enumerate(nums[1:], start=1):
cumsum[i] = cumsum[i-1] + x
return cumsum
def count_increments(self, q, q_pos, cumsum) -> int:
num_less = q_pos
if num_less == 0:
# For all x, q < x.
# No increment is necessary
return 0
sum_x = cumsum[q_pos-1]
return num_less*q - sum_x
def count_decrements(self, q, q_pos, cumsum) -> int:
n = len(cumsum)
num_more = n - q_pos
if num_more == 0:
# For all x, q > x
# No decrement is necessary
return 0
sum_x = cumsum[n-1] - (cumsum[q_pos-1] if q_pos > 0 else 0)
return sum_x - num_more*q
def minOperations(self, nums: List[int], queries: List[int]) -> List[int]:
n, m = len(nums), len(queries)
nums.sort()
cumsum = self.find_cumulative_sum( nums )
num_ops = [0]*m
for i, q in enumerate(queries):
q_pos = self.find_insert_index(q, nums)
n_inc = self.count_increments(q, q_pos, cumsum)
n_dec = self.count_decrements(q, q_pos, cumsum)
num_ops[i] = n_inc + n_dec
return num_ops
Leave a comment