leetcode1558.得到目标数组的最少函数调用次数

本文解析如何通过最少的函数调用来将数组nums调整为全0初始的数组,重点关注奇数元素的处理和偶数优化策略。通过举例和算法实现,揭示了如何通过统计奇数并逐步转换为偶数,最终达到目标数组的过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目大意

在这里插入图片描述
给你一个与 nums 大小相同且初始值全为 0 的数组 arr ,请你调用以上函数得到整数数组 nums 。

请你返回将 arr 变成 nums 的最少函数调用次数。

答案保证在 32 位有符号整数以内。

输入:nums = [1,5]
输出:5
解释:给第二个数加 1 :[0, 0] 变成 [0, 1] (1 次操作)。
将所有数字乘以 2 :[0, 1] -> [0, 2] -> [0, 4] (2 次操作)。
给两个数字都加 1 :[0, 4] -> [1, 4] -> [1, 5] (2 次操作)。
总操作次数为:1 + 2 + 2 = 5 。

输入:nums = [2,2]
输出:3
解释:给两个数字都加 1 :[0, 0] -> [0, 1] -> [1, 1] (2 次操作)。
将所有数字乘以 2 : [1, 1] -> [2, 2] (1 次操作)。
总操作次数为: 2 + 1 = 3 。

输入:nums = [4,2,5]
输出:6
解释:(初始)[0,0,0] -> [1,0,0] -> [1,0,1] -> [2,0,2] -> [2,1,2] -> [4,2,4] -> [4,2,5] (nums 数组)。

输入:nums = [3,2,2,4]
输出:7

输入:nums = [2,4,8,16]
输出:8```

解题思路

考虑将目标数组往回推,得到全0数组。
首先:如果当前数组中有奇数的存在,则上一步必然不是通过元素*2得到的,只能是某个偶数元素+1得到。
因此当前数组中有多少个奇数,我们就至少需要变换多少次。

另一方面,如果数组全是偶数了,则全元素2至少不会比某个元素+1要差。(如果数组时[0,1], 变换后是[0,2],则2或者+1的效果是一样的,其余情况肯定*2得到目标数组用的步数更少)

综上所述:总步数count=0,(1)当前数组有N个奇数,则count++N;(2)第一步统计奇数后,将奇数-1都变成偶数,然后当前数组全部元素/2,count+1.(3)重复(1)(2)步,直到元素全为0为止即可。

class Solution {
public:
    int minOperations(vector<int>& nums) {
        int ans = 0;
        int length = nums.size();

        while (true){
            int zeroNums = 0;  // 用来统计当前数组变化  后  ,有多少个0元素
            for (int i = 0; i < length; ++i){
                if (nums[i] == 0)  // 如果是0元素,则不需要变化
                    zeroNums++;
                // 如果是奇数,则必然-1变成偶数
                // 全变成偶数后,整个数组/2,在这里合成一步进行了
                else if (nums[i] & 1){ 
                    ans++;
                    nums[i] = (nums[i] - 1) / 2;
                    // 如果变化后为0,则统计数量
                    if (nums[i] == 0)
                        zeroNums++;
                }
                else  // 如果是偶数,直接/ 2
                    nums[i] = nums[i] / 2;
            }
            // 如果全部为0元素了,则不需要/ 2这一步了,直接返回结果
            if (zeroNums == length)
                break;
            // 如果仍然有元素不为0,则统计当前/ 2这一步
            ans++;
        }
        return ans;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值