c语言求一个数的位数不用循环_LeetCode基础算法题第181篇:将数字减少为零的步骤数...
技术提高是一个循序渐进的过程,所以我讲的leetcode算法题从最简单的level开始写的,然后到中级难度,最后到hard难度全部完。目前我选择C语言,Python和Java作为实现语言,因为这三种语言还是比较典型的。由于篇幅和精力有限,其他语言的实现有兴趣的朋友请自己尝试。
如果有任何问题可以在文章后评论或者私信给我。
如果有朋友希望我讲些其他话题,请在评论区留言或者私信给我。
持续分享,敬请关注。
LeetCode 1342. 将数字减少为零的步骤数(Number of Steps to Reduce a Number to Zero)
问题描述:
给定一个非负整数num,返回将其减少为零的步骤数。如果当前数为偶数,则必须将其除以2,否则,必须从中减去1。
注:
- 0 <= num <= 10^6;
示例:
C语言实现:
这个题目大家第一个想到的一定是按部就班的弄一个for循环,判断num是奇数还是偶数,奇数减1,偶数除而,返回循环的次数。
这是传统的思路。我们今天来换一个角度思考一下。
首先数字不断的除2,我想到的是二进制的右移操作。对于二进制形式来说,如果一个数是偶数,那么它二进制形式的最右边一定是0,反之一定是1,注意这里,很重要,请先记住。
按照题目所说,如果偶数就除以2,那就相当于右移动一位,如果是奇数就减一,那么是不是表明数二进制形式有多少1就要减多少次呢?
而要变成0,就要不断的右移,移动多少次?是不是二进制的长度决定的。
那么最终的结果要处理多少次,就应该是:二进制中1的数量+二进制的长度-1。
为什么要减1,因为右移到二进制形式的最左边的1,被重复计算了一次:计算1数量的时候计算了一次,最后右移动到1的时候又计算了一次。
这个算法并不复杂,不理解的跟着例子慢慢琢磨就明白了。举一个例子:
假设num = 1234,那么它的二进制形式就是"10011010010"
右移,即除以2,得到617, 二进制:"1001101001"
617是奇数,要减1,得616,二进制:"1001101000"
右移,得到308, 二进制:"100110100"
右移,得到154, 二进制:"10011010"
右移,得到77, 二进制:"1001101"
77是奇数,减1,得76, 二进制:"1001100"
右移,得到38, 二进制:"100110"
右移,得到19, 二进制:"10011"
19是奇数,减1,得18, 二进制:"10010"
右移,得到9, 二进制:"1001"
9是奇数,减1,得8, 二进制:"1000"
右移,得到4, 二进制:"100"
右移,得到2, 二进制:"10"
右移,得到1, 二进制:"1"
1是奇数,减1,得0, 二进制:"0"
对于C语言来说,我们用gun内置函数__builtin_popcount可以很方便的计算出1的数量,而二进制的长度可以用32-__builtin_clz(num)来实现,__builtin_clz是求num前导0的数量,这么一减,就是二进制的长度。
所以最终我们一行代码就可以搞定。
代码如下:
Java语言实现:
Java 的实现和C语言的实现一致。
我们用Integer.bitCount方法求1的数量,用Integer.toBinaryString(num).length()求二进制长度。最终也是一行实现。
代码如下:
Python语言实现:
Python 的实现和C语言的实现一致。
用bin(num)得出num的二进制字符串,然后用count方法求出里面字符1的数量,用len方法求二进制的长度,需要注意的是,bin方法打印的二进制字符串有两个前缀"0b",这个我们是要去掉的,所以要多减去2。
代码如下:
c语言求一个数的位数不用循环_LeetCode基础算法题第181篇:将数字减少为零的步骤数...相关推荐
- 实现链栈的各种基本运算的算法_LeetCode基础算法题第78篇:如何不用加减号实现两数的加法运算?...
一直很纠结算法的文章应该怎么写.最后觉得还是从最简单的level开始写吧,一开始就弄些重量级的,什么人工智能,机器学习的算法,还要有大量的数学以及优化的知识,小白们估计会很郁闷,当然我也不一定能做出来 ...
- 每列大于0的个数_题目1342——把一个数字减少到0的步骤数
封面来自leetcode.com 题目描述 给定一个非负整数,返回把这个数减少到0的操作步骤数.当给定的数是偶数时,把它除以2:当给定的数是奇数时,把它减去1. 示例 例1 输入:num = 14 输 ...
- 用C语言判断一个数的位数,并取出每个数字
这个方法是我在写C语言作业时想出来的 简单写下直接求一个数的位数的原理,直接手写了 知道了位数再求每个数字就比较好求了 #include<stdio.h>#include<math. ...
- php怎么求最小公倍数,C++_详解C语言求两个数的最大公约数及最小公倍数的方法,求两个正整数的最大公约数nbs - phpStudy...
详解C语言求两个数的最大公约数及最小公倍数的方法 求两个正整数的最大公约数 思路:这是一个很基本的问题,最常见的就是两种方法,辗转相除法和辗转相减法.通式分别为 f(x, y) = f(y, x%y) ...
- 求一个数各个位数之和
//求一个数各个位数之和 int parm(int n) {if(n<10){return n;}else{return parm(n/10)+n%10;} }int main() {print ...
- 用C语言求三个数的最大值与排序
用C语言求三个数的最大值与排序 1.用C语言求三个数的最大值 语法:if语句 代码如下: #include<stdio.h> int main() {int a, b, c;printf( ...
- 如何用C语言求两个数的较大值
用C语言求两个数的较大值,有两种方法: 1,常规方法,利用选择语句的 if 语句 #include<stdio.h> int main() {int a=10;int b=20;if (a ...
- Python:实现求一个数的位数之和算法(附完整源码)
Python:实现求一个数的位数之和算法 from timeit import timeit def sum_of_digits(n: int) -> int:n = -n if n < ...
- Java基础算法题(07):输入一行字符,分别统计出其中英文字母、空格、数字和其它字符的个数。
查看所有50道基础算法题请看: Java的50道基础算法题 package Demo07Character_Count; import java.util.Scanner; public class ...
最新文章
- 2021年大数据Hadoop(十五):Hadoop的联邦机制 Federation
- 5秒到1秒,记一次效果“非常”显著的性能优化
- 非常详细的transformer笔记,包括XLNet, MT-DNN, ERNIE, ERNIE2, RoBERTa
- Linux 进程通信fifo,Linux 进程通信之FIFO的实现
- 项目实例改编:利用structs2的action 实时显示图片、pdf和其他内容的框架抽取。(转)...
- 故障error: failed to run Kubelet: failed to create kubelet: misconfiguration: kubelet cgroup driver: “
- 分布式搜索elasticsearch
- 《Python编程从入门到实践》记录之类的使用
- Python自带又好用的代码调试工具Pdb学习笔记
- linux命名管道fifo通信示例
- matlab实现adf检验,ADF检验MATLAB程序资料
- excel取消隐藏_Excel教程:教你两招,批量取消隐藏工作表
- lightgbm可视化后的threshold和leaf_value是什么意思?
- 大家好!我是happy_HuHu
- PHP的bz2压缩扩展工具
- 大学计算机软件名词解释,2018北京大学计算机软件与理论考研复试通知复试经验复试英语及面试技巧...
- C#调用映美云打印机CFP535
- gitee搭建图床流程
- html栏目切换,最简单的栏目切换方法(样式系列之栏目切换篇2)
- eclipse中显示代码行数
热门文章
- Android Browser学习七 书签历史模块: 书签UI的实现
- 匈牙利命名法、骆驼命名法、帕斯卡(pascal)命名法 C#命名规范
- [小功能]禁用模板默认CSS
- win7服务器未能登入,Win7提示profile服务未能登录,无法在系统中创建怎么办
- html中el表达式遍历list,使用EL表达式访问集合
- Python+OpenCV:级联分类器(Cascade Classifier)
- error C2360: 参数初始化操作由“case”标签跳过
- 机器视觉系统设计难点有哪些?
- Halcon例程学习:print_check.hev(光学字符检测)
- linux进程fd数量,linux – 文件描述符的数量:/ proc / sys / fs / file-nr和/ proc / $pid / fd之间有什么不同?...