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

题目: 5481. 得到目标数组的最少函数调用次数

题目描述:

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

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

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

示例 1:

输入: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 。

示例 2:

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

示例 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 数组)。

示例 4:

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

示例 5:

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

提示:

1 <= nums.length <= 10^5
0 <= nums[i] <= 10^9

解题思路:

modify 算法
1)、nums 中单个一个元素 nums[i] + 1 算一次操作;
2)、nums 中的元素整体 nums[i] << = 1 , nums 中每一个元素 *2 也算作一次操作;

所以可以将 arr ----> nums 的操作转换为 对每个数字的二进制的 '0' , '1'的操作;

midmax 记录的是每个nums[i] 的二进制的位数 ;
maxNum 记录 最大的一个 midmax 的值 ;
ret 是记录需要的modify 操作的次数;

代码实现:

class Solution {
public:
    int minOperations(vector<int>& nums) {
        int i ;
        int midmax = 0  , maxNum = 0 , ret = 0 ;
        for (i = 0 ; i < nums.size() ; i ++)
        {
            midmax = -1 ;
            while (nums[i] > 0)
            {
                if (nums[i] & 1) ret ++ ;
                midmax ++ ;
                nums[i] >>= 1 ;
                
            }
            
            maxNum = max(maxNum , midmax) ;
        }
        cout <<ret  <<'\t' << maxNum << endl ; 
        return ret + maxNum ;
    }
};

算法复杂度:

时间复杂度: O(n);--- O (n) * 32 (int 最大32位)
空间复杂度:O(1)

猜你喜欢

转载自blog.csdn.net/u010155337/article/details/108177156