将数组和减半的最少操作次数

2208. 将数组和减半的最少操作次数

题目描述:给你一个正整数数组nums。每一次操作中,你可以从nums中选择任意一个数并将它减小到恰好一半。(注意,在后续操作中你可以对减半过的数继续执行操作)
请你返回将nums数组和至少减少一半的最少操作数。

在这里插入图片描述

解题思路:该题目解题思路很简单,也就是查找数组中最大的数值进行减半操作,直到操作之后的数组能达到原来数组和的一半。基于这个思路,我们可以使用一个最为简单思路进行解决,也就是每次筛选最大的数值,定位到当前数值的索引,然后对其减半操作,进行判断,直至达到原来数组和的一半以下。

class Solution:
    def halveArray1(self, nums: list) -> int:
        sumnum = sum(nums)
        # 需要减少的数字
        subnum = sumnum / 2
        res = 0
        while sumnum - sum(nums) < subnum:
            maxnum = max(nums)
            idx = nums.index(maxnum)
            nums[idx] = nums[idx] / 2
            res += 1
        return res

但是该代码的时间复杂度为 $O(n^2),在该题目中就会超时,可以注意到,每次都是挑选数组中较大的数值,则可以使用优先队列进行优化代码。优化之后的代码时间复杂度就是O(n),则可以通过测试。

class Solution:
    def halveArray(self, nums: list) -> int:
        sumnum = sum(nums)
        divnum = sumnum / 2
        heap = []
        for i in nums:
            heapq.heappush(heap, -i)
        res = 1
        s = -heapq.heappop(heap) / 2
        while sumnum - s > divnum:
            sumnum -= s
            heapq.heappush(heap, -s)
            s = -heapq.heappop(heap) / 2
            res += 1
        return res
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,以下是使用C语言实现四种算法寻找数组最大值的代码,包含主函数以及统计关键字比较次数: ```c #include <stdio.h> #include <stdlib.h> #include <time.h> // 蛮力法 int max_brute(int arr[], int n, int *count) { int max = arr[0]; for (int i = 1; i < n; i++) { (*count)++; if (arr[i] > max) max = arr[i]; } return max; } // 分治法 int max_divide(int arr[], int l, int r, int *count) { if (l == r) return arr[l]; int mid = (l + r) / 2; int max_left = max_divide(arr, l, mid, count); int max_right = max_divide(arr, mid + 1, r, count); (*count) += 2; return max_left > max_right ? max_left : max_right; } // 减一法 int max_sub1(int arr[], int n, int *count) { int max = arr[0]; for (int i = 1; i < n; i += 2) { (*count)++; if (arr[i] > arr[i - 1]) { (*count)++; if (arr[i] > max) max = arr[i]; } else { (*count)++; if (arr[i - 1] > max) max = arr[i - 1]; } } if (n % 2 != 0) { (*count)++; if (arr[n - 1] > max) max = arr[n - 1]; } return max; } // 减半法 int max_halve(int arr[], int n, int *count) { int max = arr[0]; int left = 0, right = n - 1; while (left <= right) { (*count)++; if (left == right) { (*count)++; if (arr[left] > max) max = arr[left]; break; } (*count)++; if (arr[left] > arr[right]) { (*count)++; if (arr[left] > max) max = arr[left]; left++; } else { (*count)++; if (arr[right] > max) max = arr[right]; right--; } } return max; } int main() { srand(time(NULL)); // 用时间戳初始化随机数生成器 int n = 100; // 数组长度 int arr[n]; for (int i = 0; i < n; i++) { arr[i] = rand() % 1000; // 生成0~999之间的随机整数 } // 蛮力法 int count_brute = 0; int max_brute_val = max_brute(arr, n, &count_brute); printf("蛮力法:最大值为%d,比较次数为%d\n", max_brute_val, count_brute); // 分治法 int count_divide = 0; int max_divide_val = max_divide(arr, 0, n - 1, &count_divide); printf("分治法:最大值为%d,比较次数为%d\n", max_divide_val, count_divide); // 减一法 int count_sub1 = 0; int max_sub1_val = max_sub1(arr, n, &count_sub1); printf("减一法:最大值为%d,比较次数为%d\n", max_sub1_val, count_sub1); // 减半法 int count_halve = 0; int max_halve_val = max_halve(arr, n, &count_halve); printf("减半法:最大值为%d,比较次数为%d\n", max_halve_val, count_halve); return 0; } ``` 这个代码实现了四种算法,其中每种算法都有一个计数器来统计比较次数。主函数中首先随机生成一个长度为n的数组,然后依次调用四种算法,并输出每种算法的最大值和比较次数

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值