leetcode1558题解【贪心】
leetcode1558.得到目标数组的最少函数调用次数
算法
贪心
时间复杂度O(nlogN),N为数组中最大的那个数。
1.题意就是给定一个函数,该函数有两种功能,一种就是将数组中的所有数同乘以2,另一种就是将数组中的某个数加1。给定一个数组nums,让你将初始值全为0的数组arr通过调用给定的函数来变成nums。问最少调用次数。
2.刚开始模拟了一番,但因为考虑的方法不对(至于哪里不对呢,就是一开始我就把数组的值都加1了一遍,然后再同乘以2,最后再一个个补1,这么做显然不利于减少次数。至于当时为啥这么想,估计是脑子抽了),最终无果。
3.接下来步入正题,我们可以这么想。当初始值都为0时,我们可以使部分值首先加1(即最终要变成的较大的值),让它们首先乘以2,不断乘,乘到一定程度再处理。但这么做有个问题,让哪部分值先变成1呢?还有就是乘到哪种程度呢?
这个地方的确是个难点,不太容易想。如果直接模拟的话不太容易。
数组中谁乘2的次数最多,当然是目标值最大的那个数乘的次数最多,其他目标值较小的就相对来说乘的次数较少。我们可以贪心地让那些乘的次数较少的包含在乘的次数最多里面,至于它具体是怎么乘的,我们不用考虑太多,这就是贪心算法的好处。
如何计算每个数最终乘的次数,我们可以分情况讨论:
为了方便,我们可以从目标值向初始值变化。
对于奇数,可以先让其变为偶数(变为偶数这个过程即减1,这个需要单独记录),然后再除2,每除一次就记录一次。
对于偶数,就除2,每除一次就记录一次。可能除着除着就变成奇数了,比如250,这时候就执行上一步。
最终,数组中的值就都变成0了。
4.总之,这道题的基本思路就是求出目标数组中最大值变成0需要除2的次数,以及该数组中每个数需要减1的次数(什么时候减,就是为奇数的时候减),二者相加即为答案。
C++代码
class Solution {
public:
int minOperations(vector<int>& nums) {
int len = nums.size();
int res = 0;
int mx = 0; //记录乘以2的最大次数
for(int i = 0; i < len; i++){
int cnt = 0;
while(nums[i]){
if(nums[i] % 2 == 1){
nums[i] -= 1; //把它变成偶数
res++;
}
if(nums[i] > 0){
nums[i] /= 2;
++cnt;
}
}
mx = max(mx, cnt);
}
res += mx;
return res;
}
};
leetcode1558题解【贪心】的更多相关文章
- 洛谷P2460 [SDOI2007]科比的比赛(题解)(贪心+搜索)
科比的比赛(题解)(贪心+搜索) 标签:算法--贪心 阅读体验:https://zybuluo.com/Junlier/note/1301158 贪心+搜索 洛谷题目:P2460 [SDOI2007] ...
- PAT甲级1007题解——贪心
题目分析:对于每一个点来说,如果选择合并入包含前一个点的序列那么只有在前一个点的序列不为负数(这里指的是包含前一个位置的数的一个连续序列的和不为负数),当前点才会将自己也加入这个子序列,否则,当前点则 ...
- CF336C-Vasily the Bear and Sequence题解--贪心
题目链接 https://www.luogu.org/problemnew/show/CF336C 分析 一个比较妙的贪心 我们要让最后\(and\)起来的数被\(2^k\)整除且\(k\)最大,我们 ...
- Codeforces 515C 题解(贪心+数论)(思维题)
题面 传送门:http://codeforces.com/problemset/problem/515/C Drazil is playing a math game with Varda. Let’ ...
- 洛谷P2672 推销员 题解 贪心
题目链接:https://www.luogu.org/problem/P2672 这道题目是贪心,贪心的思想是: 选择 \(m\) 户人家的最大疲劳值应该是以下两种方案中的较大值: 方案一:选择 \( ...
- Leetcode题解 - 贪心算法部分简单题目代码+思路(860、944、1005、1029、1046、1217、1221)
leetcode真的是一个学习阅读理解的好地方 860. 柠檬水找零 """ 因为用户支付的只会有5.10.20 对于10元的用户必须找一个5 对于20元的用户可以找(三 ...
- BZOJ 3252题解(贪心+dfs序+线段树)
题面 传送门 分析 此题做法很多,树形DP,DFS序+线段树,树链剖分都可以做 这里给出DFS序+线段树的代码 我们用线段树维护到根节点路径上节点权值之和的最大值,以及取到最大值的节点编号x 每次从根 ...
- Crossing River 题解(贪心)
题目链接 题目大意 t组数据(t<=20) 给你n个人(n<=1000)过河,每个人都有权值,一条船,每次船最多运2个人,每次的花费为两个人的较大花费 求所有人都过河需要的最小花费 题目思 ...
- 洛谷P1484 种树&洛谷P3620 [APIO/CTSC 2007]数据备份 题解(堆+贪心)
洛谷P1484 种树&洛谷P3620 [APIO/CTSC 2007]数据备份 题解(堆+贪心) 标签:题解 阅读体验:https://zybuluo.com/Junlier/note/132 ...
随机推荐
- python编程中的并发------多线程threading模块
任务例子:喝水.吃饭动作需要耗时1S 单任务:(耗时20s) for i in range(10): print('a正在喝水') time.sleep(1) print('a正在吃饭') time. ...
- Selenium的WebDriver API元素定位中的XPath和CSS
元素的定位和操作是自动化测试的核心部分,其中操作又是建立在定位的基础上的. 浏览器的常规操作 import time from selenium import webdriver # 打开浏览器 dr ...
- Java通过反射加载的类,变量无法注入
//之前都是直接newInstance的到obj,类中的变量无法被注入//Object obj = aClass.newInstance(); //改成如下方式的到bean,变量就能顺利被注入 ,其他 ...
- Android开发之强大的网络判断工具,判断是否联网,判断是wifi还是3g网络等java工具代码类
作者:程序员小冰,CSDN博客:http://blog.csdn.net/qq_21376985, 转载请说明出处. 给大家分享一个Android开发者常用的工具类.主要针对网络判断的 功能强大.下面 ...
- unity2D物理引擎之-Rigidbody 2D
虽然Rigidbody 2D大致上可以看成是Rigidbody的2D化,大部分功能也是一致的,但是还是有一些细节问题. 一些事项: 1.任何添加到同一个 GameObject身上或者其子物体身上的 2 ...
- MySQL 增删查改 必知必会
MySQL 数据库中的基础操作 3.表的修改 对表的表名.字段.字段类型.字段长度.约束等进行修改. 3.1 表的名称修改 -- 语法: ALTER TABLE 库名.表名 RENAME TO 新表名 ...
- SpringBoot系列之从入门到精通系列教程
对应SpringBoot系列博客专栏,例子代码,本博客不定时更新 Spring框架:作为JavaEE框架领域的一款重要的开源框架,在企业应用开发中有着很重要的作用,同时Spring框架及其子框架很多, ...
- vue computed实现原理
在 Vue.prototype._init 方法中的 initState 中有一个对于computed 的判断,如果有则执行 initComputed 方法初始化 computed. function ...
- python3之range()
python range() 函数可创建一个整数列表,一般用在 for 循环中. 函数语法(左闭右开) Python3 range() 函数返回的是一个可迭代对象(类型是对象),而不是列表类型, 所以 ...
- basicInterpreter1.02 增加对for循环的支持
源码下载:https://files.cnblogs.com/files/heyang78/basicInterpreter102-20200531-2.rar 输入: for x= to print ...