春节假期这么长,干啥最好?当然是折腾一些算法题了,下面给大家讲几道一行代码就能解决的算法题,当然,我相信这些算法题你都做过,不过就算做过,也是可以看一看滴,毕竟,你当初大概率不是一行代码解决的。

学会了一行代码解决,以后遇到面试官问起的话,就可以装逼了。

一、2 的幂次方

问题描述:判断一个整数 n 是否为 2 的幂次方

对于这道题,常规操作是不断这把这个数除以 2,然后判断是否有余数,直到 n 被整除成 1 。

我们可以把 n 拆成二进制看待处理的,如果 n 是 2 的幂次方的话,那么 n 的二进制数的最高位是 1,后面的都是 0,例如对于 16 这个数,它的二进制表示为 10000。

如果我们把它减 1,则会导致最高位变成 0,其余全部变成 1,例如 10000 - 1 = 01111。

然后我们把 n 和 (n - 1)进行操作,结果就会是 0,例如(假设 n 是 16)

n & (n-1) = 10000 & (10000 - 1) = 10000 & 01111 = 0

也就是说,n 如果是 2 的幂次方,则 n & (n-1) 的结果是 0,否则就不是,所以代码如下

int isPow(n){return (n & (n - 1)) == 0;
}

二、一行代码搞定经典的约瑟夫环

约瑟夫环问题,我相信大家在大一大二的时候就接触过了,很多人也都会拿来作为环形链表的一个应用,然而环形链表并非最优的解决方法,今天我就用一行代码干掉它,并且几乎算是最优解了。

鉴于有些人把这道题忘了,我还是把这道题的描述贴出来一下吧

问题描述:编号为 1-N 的 N 个士兵围坐在一起形成一个圆圈,从编号为 1 的士兵开始依次报数(1,2,3…这样依次报),数到 m 的 士兵会被杀死出列,之后的士兵再从 1 开始报数。直到最后剩下一士兵,求这个士兵的编号。

先给出代码,后面在解释。

int f(int n, int m){return n == 1 ? n : (f(n - 1, m) + m - 1) % n + 1;
}

原理是这样的:

如果我们把士兵删除后,重新给这些士兵编号的话,那么删除前和删除后,这些编号存在某种数学关系,我们只需要找出这个关系即可。

我们定义递归函数 f(n,m) 的返回结果是存活士兵的编号,显然当 n = 1 时,f(n, m) = 1。假如我们能够找出 f(n,m) 和 f(n-1,m) 之间的关系的话,我们就可以用递归的方式来解决了。我们假设人员数为 n, 报数到 m 的人就自杀。则刚开始的编号为


1

m - 2

m - 1

m

m + 1

m + 2

n

进行了一次删除之后,删除了编号为 m 的节点。删除之后,就只剩下 n - 1 个节点了,删除前和删除之后的编号转换关系为:

删除前 — 删除后

… — …

m - 2 — n - 2

m - 1 — n - 1

m ---- 无(因为编号被删除了)

m + 1 — 1(因为下次就从这里报数了)

m + 2 ---- 2

… ---- …

新的环中只有 n - 1 个节点。且删除前编号为 m + 1, m + 2, m + 3 的节点成了删除后编号为 1, 2, 3 的节点。

假设 old 为删除之前的节点编号, new 为删除了一个节点之后的编号,则 old 与 new 之间的关系为 old = (new + m - 1) % n + 1。

这样,我们就得出 f(n, m) 与 f(n - 1, m)之间的关系了,而 f(1, m) = 1.所以我们可以采用递归的方式来做。代码如下:

注:有些人可能会疑惑为什么不是 old = (new + m ) % n 呢?主要是因为编号是从 1 开始的,而不是从 0 开始的。如果 new + m == n的话,会导致最后的计算结果为 old = 0。所以 old = (new + m - 1) % n + 1.

int f(int n, int m){if(n == 1)   return n;return (f(n - 1, m) + m - 1) % n + 1;
}

怎么不是一行而是两行?如果你经常刷题,那肯定希望自己的代码看起来越短越简介越好,至于会不会变的更难理解?我懒的理,所以代码如下

int f(int n, int m){return n == 1 ? n : (f(n - 1, m) + m - 1) % n + 1;
}

当然,我之前写过一篇文章,用了三种方法来解决约瑟夫环,感兴趣的也可以看:记一道阿里笔试题:我是如何用一行代码解决约瑟夫环问题的

只出现一次是数

问题描述:给你一个整型数组,数组中有一个数只出现过一次,其他数都出现了两次,求这个只出现了一次的数。

这道题可能很多人会用一个哈希表来存储,每次存储的时候,记录 某个数出现的次数,最后再遍历哈希表,看看哪个数只出现了一次。这种方法的时间复杂度为 O(n),空间复杂度也为 O(n)了。

然而这道题其实可以采用异或运算来解决,两个相同的数异或的结果是 0,一个数和 0 异或的结果是它本身,并且异或运算支持交换律,基于这个特点,我们只需要把这一组整型全部异或一下,最后的结果就是我们要找的数了。

例如这组数据是:1, 2, 3, 4, 5, 1, 2, 3, 4。其中 5 只出现了一次,其他都出现了两次,把他们全部异或一下,结果如下:

由于异或支持交换律和结合律,所以:

123451234 = (11)(22)(33)(44)5= 00005 = 5。

通过这种方法,可以把空间复杂度降低到 O(1),而时间复杂度不变,相应的代码如下

int find(int[] arr){int tmp = arr[0];for(int i = 1;i < arr.length; i++){tmp = tmp ^ arr[i];}return tmp;
}

说好的一行代码的呢?

这不是为了先让你看的懂吗?一行代码解决方案如下:

// 例如使用这个函数的时候,我们最开始传给 i 的值是 1,传给 result 的是 arr[0]
//例如 find(arr, 1, arr[0])
int find(int[] arr,int i, int result){return arr.length <= i ? result : find(arr, i + 1, result ^ arr[i]);
}

实不相瞒,这道题用了一行代码之后,更加复杂 + 难懂了,,,,,,不好意思,我错了,不该把简单的问题搞复杂了再扔给面试题的。

四、n 的阶乘

问题描述:给定一个整数 N,那么 N 的阶乘 N! 末尾有多少个 0?例如: N = 10,则 N!= 3628800,那么 N! 的末尾有两个0。

我先给出个代码让大家品尝一下,在细细讲解

int f(n){return n == 0 ? 0 : n / 5 + f(n / 5);
}

对于这道题,常规操作是直接算 N!的值再来除以 10 判断多少个 0 ,然而这样肯定会出现溢出问题,并且时间复杂度还大,我们不妨从另一个思路下手:一个数乘以 10 就一定会在末尾产生一个零,那么,我们是否可以从哪些数相乘能够得到 10 入手呢?

答是可以的,并且只有 2 * 5 才会产生 10。

注意,4 * 5 = 20 也能产生 0 啊,不过我们也可以把 20 进行分解啊,20 = 10 * 2。

于是,问题转化为 N! 种能够分解成多少对 2*5,再一步分析会发现,在 N!中能够被 2 整除的数一定比能够被 5 整除的数多,于是问题近似转化为求 1…n 这 n 个数中能够被 5 整除的数有多少个

注意,像 25 能够被 5整除两次,所以25是能够产生 2 对 2 * 5滴。有了这个思路,代码如下:

int f(int n){int sum = 0;for(int i = 1; i <= n; i++){int j = i;while(j % 5 == 0){sum++;j = j / 5;}}return sum;
}

然而进一步拆解,我们发现

当 N = 20 时,1~20 可以产生几个 5 ?答是 4 个,此时有 N / 5 = 4。

当 N = 24 时,1~24 可以产生几个 5 ?答是 4 个,此时有 N / 5 = 4。

当 N = 25 时,1~25 可以产生几个 5?答是 6 个,主要是因为 25 贡献了两个 5,此时有 N / 5 + N / 5^2 = 6。

可以发现 产生 5 的个数为 sum = N/5 + N/5^2 + N/5^3+….

于是,一行代码就可以搞定它了

int f(n){return n == 0 ? 0 : n / 5 + f(n / 5);
}

总结

有木觉得很牛逼?以后面试官问你这些题,你就把这行代码扔给他!!!

当然,想要一直保持牛逼,还得多看一些算法书,我也有整理了一些

在此贡献给大家,都是一些值得看的算法书

大家可以在我的公众号『帅地玩编程』获取『我要学算法』获取下载链接。

老铁,要不点个赞再走可好?么么哒

1、给俺点个赞呗,可以让更多的人看到这篇文章,顺便激励下我,嘻嘻。

2、老铁们,关注我的原创微信公众号「帅地玩编程」,专注于写算法 + 计算机基础知识(计算机网络+ 操作系统+数据库+Linux)。

保存让你看完有所收获,不信你打我。后台回复『电子书』送你一份精选电子书大礼包,包含各类技能的优质电子书。

作者简洁

作者:大家好,我是帅地,从大学、校招一路走来,深知算法计算机基础知识的重要性,所以申请了一个微星公众号『帅地玩编程』,专业于写这些底层知识,提升我们的内功,帅地期待你的关注,和我一起学习。 转载说明:未获得授权,禁止转载

牛逼!一行代码居然能解决这么多曾经困扰我半天的算法题相关推荐

  1. 什么是最牛逼的代码?

    2019独角兽企业重金招聘Python工程师标准>>> 接触IT6年多,工作2年多,我一直在思考着这样一个问题:什么的代码,才是最牛逼的代码? 直到最近,我想才得出这么一个结论. 我 ...

  2. (博弈论)一行代码就能解决的智力题

    (博弈论)一行代码就能解决的智力题 我在闲暇时逛微信公众号,发现了三道类似于博弈论的题,这三道题来自LeetCode ,我认为非常有趣,于是贴在我的博客里,以下是这位大佬的链接地址,大家对算法感兴趣的 ...

  3. 那些只有几行,但是却非常牛逼的代码!

    原文地址:https://www.toutiao.com/i6800262027450253836/ 1.no code 项目地址: https://github.com/kelseyhightowe ...

  4. 牛逼,手机居然可以无线投屏到笔记本电脑!

    在我们的生活中,有时候开会演示的时候,会用到投影仪,这样就大家就可以看到你电脑屏幕上的内容了.但是,有时候需要演示手机的操作.这时我们不太可能让大家挤在一起看你操作手机吧(也不太现实). 甚至有时候想 ...

  5. 一行代码就能解决微服务分布式事务问题,你知道GTS怎么做到的吗?

    2019独角兽企业重金招聘Python工程师标准>>> GTS直播火热报名中,直播直通车 一.GTS (Global Transaction Service)是啥? GTS(全局事务 ...

  6. Java 11 正式发布,这 8 个逆天新特性教你写出更牛逼的代码

    美国时间 09 月 25 日,Oralce 正式发布了 Java 11,这是据 Java 8 以后支持的首个长期版本. 为什么说是长期版本,看下面的官方发布的支持路线图表. 可以看出 Java 8 扩 ...

  7. 优秀的java代码_像这样写,Java菜鸟也能写出牛逼的代码

    场景一 有时候我们会遇到一个方法就是占满了整个屏幕,其中各种if else 判断 ,for 循环嵌套,时不时来穿插着各种a b c参数,让人看得实在是眼花缭乱.让后面维护的人望而却步,也实在的代码块后 ...

  8. 推荐14个牛逼的代码编辑网站

    今天我将跟大家分享一些可以展示你代码的网站,它们都提供在线预览功能,所以别人可以看到你的代码如何运行.它们有时候也被称作"代码广场". 它们不仅仅提供简单的代码展示功能,还提供很多 ...

  9. 这个代码是我见过最牛逼的代码

    上代码: #include<iostream> using namespace std; int main(){int res=0;int n; scanf("%d", ...

最新文章

  1. 选择适合页面或应用程序的数据查看机制
  2. date比较大小 mybatis_MyBatis版本升级导致OffsetDateTime入参解析异常问题复盘
  3. 【数据挖掘】中文期刊点评
  4. 关于使用 ./ 执行sh文件报错-bash: ./startup.sh: /bin/sh^M: bad interpreter: No such file or directory
  5. C语言变量的定义包括变量存储类型和变量的什么?
  6. How Tomcat works — 一、怎样阅读源码
  7. CSS中加号、星号及其他符号的作用
  8. SpringBoot-Jsoup做java简单-爬虫
  9. esri-leaflet入门教程(5)- 动态绘制图形
  10. C ++中的初始化程序列表– std :: initializer_list
  11. hdu 1011 Starship Troopers (树形背包dp)
  12. 佳能7660cdn 评价_佳能Canon LBP7660Cdn 驱动
  13. 用IO流读取trs文件
  14. Python turtle制作书法作品——《鸟鸣涧》
  15. 实时频谱分析仪作下变频器的技术实现
  16. 阅读Disentangling and Unifying Graph Convolutions for Skeleton-Based Action Recognition(CVPR2020)
  17. データファイルのアップロードとダウンロード
  18. 「日常训练知识学习」树的直径(POJ-1849,Two)
  19. openGauss之gsql工具的使用
  20. 基于titanic数据集介绍数据分析处理流程

热门文章

  1. 西安科技大学计算机图形学课程设计,长方体体的光照效果计算机图形学课程设计...
  2. 【辐射4】用Mod Organizer载入mod时CBBE身形无效的情况(身体贴图错误、黑块等等)(做个记录)
  3. 谭松波酒店评价情感分析代码以及数据集获取
  4. 当程序员争论甜咸粽子哪个更好吃时……| 每日趣闻
  5. 使用颜色(color)资源
  6. 【数据库开发工具】上海道宁带来Navicat 16以及多种Navicat工具,为您提供构建、管理和维护数据库的新方法
  7. Windows系统alt+数字键 的特殊字符集
  8. 【Android 日常学习】我逆向了微信数据库——微信如何大幅度提升交互性能
  9. 高分子PEG磷酸盐mPEG-phosphoric acid,Phosphate PEG,甲氧基聚乙二醇磷酸,可用于修饰金属氧化物表面
  10. 使用vtk提取模型模型边线2021-01-24