现在我们需要求得将 nums 转换为「锯齿数组」所需的最小操作次数。不失一般性,我们设我们最后求得的「锯齿数组」满足每一个偶数索引对应的元素都大于其相邻的元素。因为操作的先后并不会影响最终结果,所以我们若我们要对某些偶数下标的元素进行操作,则先完成该些操作,然后再统一对奇数下标的元素进行操作,设数组 p 为对 nums 某些偶数下标的元素进行操作后的数组,那么为了使数组 p 为满足每一个偶数索引对应的元素都大于其相邻的元素的「锯齿数组」,其奇数下标的元素都需要小于其相邻元素的最小值,即为了使某一个奇数下标位置 i 满足要求的最少操作次数 c_i = \max(p[i] - q(i) + 1, 0),其中 q(i) 表示数组 p 中位置 i 相邻元素的最小值,因为若我们对某个偶数下标的元素进行了操作,则该元素相邻的奇数下标元素所需要的操作次数只增不减,但是总的操作次数一定增加了,所以最优解中一定不会存在对偶数下标操作的情况。那么我们对 nums 中每一个奇数位置 i 的 c_i 求和即为此时求每一个偶数索引对应的元素都大于其相邻的元素的「锯齿数组」的最少操作的次数。对于求每一个奇数索引对应的元素都大于其相邻的元素的「锯齿数组」的最小操作次数同理,最终返回两者的较小值即可。
代码
[sol1-Python3]
1 2 3 4 5 6 7 8 9 10 11 12 13 14
classSolution: defmovesToMakeZigzag(self, nums: List[int]) -> int: defhelp(pos: int) -> int: res = 0 for i inrange(pos, len(nums), 2): a = 0 if i - 1 >= 0: a = max(a, nums[i] - nums[i - 1] + 1) if i + 1 < len(nums): a = max(a, nums[i] - nums[i + 1] + 1) res += a return res
classSolution { public: inthelp(vector<int>& nums, int pos){ int res = 0; for (int i = pos; i < nums.size(); i += 2) { int a = 0; if (i - 1 >= 0) { a = max(a, nums[i] - nums[i - 1] + 1); } if (i + 1 < nums.size()) { a = max(a, nums[i] - nums[i + 1] + 1); } res += a; } return res; }
publicintHelp(int[] nums, int pos) { int res = 0; for (int i = pos; i < nums.Length; i += 2) { int a = 0; if (i - 1 >= 0) { a = Math.Max(a, nums[i] - nums[i - 1] + 1); } if (i + 1 < nums.Length) { a = Math.Max(a, nums[i] - nums[i + 1] + 1); } res += a; } return res; } }
staticinlineintmin(int a, int b) { return a < b ? a : b; }
staticinlineintmax(int a, int b) { return a > b ? a : b; }
inthelp(constint *nums, int numsSize, int pos) { int res = 0; for (int i = pos; i < numsSize; i += 2) { int a = 0; if (i - 1 >= 0) { a = max(a, nums[i] - nums[i - 1] + 1); } if (i + 1 < numsSize) { a = max(a, nums[i] - nums[i + 1] + 1); } res += a; } return res; }
var movesToMakeZigzag = function(nums) { returnMath.min(help(nums, 0), help(nums, 1)); }
consthelp = (nums, pos) => { let res = 0; for (let i = pos; i < nums.length; i += 2) { let a = 0; if (i - 1 >= 0) { a = Math.max(a, nums[i] - nums[i - 1] + 1); } if (i + 1 < nums.length) { a = Math.max(a, nums[i] - nums[i + 1] + 1); } res += a; } return res; };
funcmovesToMakeZigzag(nums []int)int { help := func(pos int)int { res := 0 for i := pos; i < len(nums); i += 2 { a := 0 if i-1 >= 0 { a = max(a, nums[i]-nums[i-1]+1) } if i+1 < len(nums) { a = max(a, nums[i]-nums[i+1]+1) } res += a } return res }
return min(help(0), help(1)) }
funcmin(a, b int)int { if a > b { return b } return a }
funcmax(a, b int)int { if b > a { return b } return a }