首先一定要有这种思想就是他求的是mincost这个值,所以应该往动态规划上去想。而且这个问题的动态规划肯定是二维的,这张基本思想要有。 这里的动态规划也是从放置的最后一个mailbox出发来想,当最后一个mailbox放置的位置定了之后,那么最终的cost就是放置最后一个mailbox造成的cost和前面的相应的子问题造成的cost。也就是说我们要求解的是最后一个mailbox覆盖若干个house的cost以及他相应子问题cost的和的最小值。这样状态转移方程就比较清晰了 接下来需要考虑的问题就是,对于有若干个房子,一个mailbox的情况下,怎样放置这个mailbox比较好,这个比较容易想到,应该是所有房子位置的中位数,cost就是所有房子减去中位数的绝对值之和,我下面代码里面的写法本质也是一样的 这边要特别特别特别注意边界,一定要想的特别清楚,可以用特殊情况来考虑
class Solution: def minDistance(self, houses: List[int], k: int) -> int: def cal_cost(left,right): total_dis = 0 while left<right: total_dis += houses[right]-houses[left] left += 1 right -= 1 return total_dis houses.sort() cost = [[0]*len(houses) for _ in range(len(houses))] for i in range(len(houses)-1): for j in range(i,len(houses)): cost[i][j] = cal_cost(i,j) dp = [[float('inf')]*(len(houses)+1) for _ in range(k+1)] for i in range(k+1): dp[i][0] = 0 for i in range(1,k+1): for j in range(1,len(houses)+1): for m in range(j): #print('m,j,cost',m,j,cost(m,j-1)) dp[i][j] = min(dp[i][j],dp[i-1][m]+cost[m][j-1]) return dp[-1][-1]一次面试面到的题目是,这个cost是距离的平方。当cost的距离的平方的时候,对于基础的情况,也就是一个mailbox,多个house的情况下,应该将mailbox放置在均值的情况下cost最小,这个推导可以通过将cost写出来然后求导为0实现。换句话说,对于一个mailbox的情况,最小的cost就是这些house位置的方差。其他的解法跟上面这道题目是一样的。 下面讲一下如何来O(1)时间计算一段stream of numbers。首先需要进行推导化简得到如下结论:
variance = 所有数的平方和-n*平均数的平方完整代码如下:
class variance_calculator: def __init__(self): self._square_sum = 0 self._count = 0 self._sum = 0 def add(self, number): self._count += 1 self._sum += number self._square_sum += number * number def get_variance(self): curr_mean = self._sum / self._count curr_variance = self._square_sum - self._count * curr_mean * curr_mean return curr_variance vc = variance_calculator() nums = [1,2,3,4] for num in nums: vc.add(num) print(vc.get_variance())