题目链接
题目梗概
一共n堆纸牌,每堆纸牌数量不同,需要对这些纸牌进行移动,来使得每堆纸牌数量相等。每次可以移动一堆里的多张纸牌,但只能移动到相邻牌堆中。
输入n堆牌堆的纸牌数,输出均分纸牌的最少移动次数。
解题思路
计算所有牌堆的纸牌数,进而计算牌数平均值。对于每堆牌堆而言,超过平均数的牌要被转移,低于平均数的牌需要被补给,并把每堆牌需要的数另存储到一个数组中,正数代表需要转移的牌数,负数代表需要补充的牌数。
如果考虑每次挪动牌数最多的那一堆并选择挪向最需要牌的那一边,这种方案需要的数据结构或是函数可能较为复杂。所以尝试考虑一种线性方案。
既然选择线性方案,那就从对数组遍历一次,并结合递归的思想,从数组的首元素开始考虑。
- 如果这个元素是正数(牌数大于平均值),那么它多出来的部分必定要向旁边(因为是首元素只能向右边转移)转移,那么该数组的转移次数就等于1 + 剩下的右边子数组的转移数;即 f(i, n) = f(i+1, n) + 1 ,i < n。
- 如果这个元素是负数(牌数小于平均值),那么它缺失的部分必定需要从旁边补充,即该元素的右边的元素必定要向该元素转移一次,那么该数组的转移次数就等于1+ 剩下的右边子数组的转移数;即 f(i, n) = f(i+1, n) + 1 ,i < n。
- 如果这个元素是零(牌数等于平均值),那么它就不需要被转移或补充,该数组的转移次数就等于右边子数组的转移数;即 f(i, n) = f(i+1, n),i < n。
函数功能
- func函数
递归处理数组,根据当前下标idx对应的元素,判断是否+1转移次数,然后再加上剩下的子数组的转移次数。
这里的函数参数传递的是数组的地址,这样在递归调用函数时,不会再对a数组进行拷贝,可以节省空间和时间。
完整代码
#in