LeetCode每日一题之排列硬币
前言:
大家好,今天是LeetCode每日一题的第十天,,给大家分享的是排列硬币,难度系数两颗星!废话不多说,先上题目!
1.1 题目要求
题目类型:排列硬币
题目内容:
总共有n枚硬币,将它们摆成一个阶梯形状,第k行就必须正好有k枚硬币。
给定一个数字n,找出可形成完整阶梯的总行数。
注意事项:n是一个非负整数,并且在32位有符号整型的范围内。
1.2 解题方法
1.2.1 使用迭代法处理
1.解题思路
假设已有n枚硬币,按照题目要求把它们摆成一个阶梯形状,同时要求第k行就必须正好有k枚硬币,那么应该怎样排列呢?
假设硬币总数为10,组成阶梯状情况如下:
行数 | 硬币排列 | 剩余数量 | 大小比较 | 是否结束 |
---|---|---|---|---|
1 | 0 | 9 (10-1) | 9>2 | 否 |
2 | 0 0 | 7 (10-1-2) | 7>3 | 否 |
3 | 0 0 0 | 4 (10-1-2-3) | 4=4 | 否 |
4 | 0 0 0 0 | 3 (10-1-2-3-4) | 0<5 | 是 |
注意:
- 硬币排列中的0表示硬币;
- 大小比较是指判断硬币的剩余数量与下一行的硬币个数的大小关系;
- 是否结束是指剩余数量是否小于等于下一行个数, 若剩余数小于下一行个数, 则排列结束,并返回当前行数
2.代码实现
- 测试代码
package com.kuang.leetcode9;/*** @ClassName ArrangeCoin* @Description 排列硬币* @Author 狂奔の蜗牛rz* @Date 2021/8/30*/
public class ArrangeCoin {//主方法测试public static void main(String[] args) {//测试存在10个硬币时,形成完整阶梯形状返回的总行数System.out.println(arrangeCoins(10));}/*** 使用迭代法解决硬币排列问题* @param n 硬币总数(在32位有符号整型范围内的非负整数)* @return 返回值为(形成完整阶梯形状)总行数*/public static int arrangeCoins(int n) {//编写for循环体/*** 定义变量i, 表示行数* 指针i的初值为多少?* 要从第一行开始, 所以其初值为1* i的取值范围为多少?* 硬币数量i不能超过总数n, 即 i <= n*/for (int i = 1; i <= n; i++) {/*** 由于题干中要求第i行的元素也为i个,* 因此硬币剩余数量为总数n减去当前行的硬币个数i*/n = n - i;//判断n(剩余硬币数量)是否小于等于i(当前行的硬币个数)if(n <= i) {//若n(剩余数)小于i(当前行个数), 将当前行的个数i进行返回return i;}}//若当前硬币数不能组成阶梯状, 则返回的排列行数为0return 0;}
}
- 测试结果
结果:测试结果与预期相同!
1.2.2 使用二分法查找处理
1.解题思路
假设最多可以排列n行,x是第n行的硬币个数,那么每行排列的硬币个数分别为 1 2 3 4 … x;
同时n为每行硬币相加之和 (即满足n=1+2+3+4+…+x),也就是说从1到n行,会存在一个x值,使得等式1+2+3+ … +x=n成立;
因此我们可以通过使用二分法从1到n行定位到那个x值
2.代码实现
- 测试代码
package com.kuang.leetcode9;/*** @ClassName ArrangeCoin* @Description 排列硬币* @Author 狂奔の蜗牛rz* @Date 2021/8/30*/
public class ArrangeCoin {//主方法测试public static void main(String[] args) {//测试存在10个硬币时,形成完整阶梯形状返回的总行数System.out.println("使用二分法排列硬币:"+arrangeCoins2(10));}/*** 使用二分查找法处理硬币排列* @param n 硬币总数(在32位有符号整型范围内的非负整数)* @return 返回值为(形成完整阶梯形状)总行数*/public static int arrangeCoins2(int n) {//定义low和high变量, 分别表示左右指针(其初值分别为左右边界值)int low = 0, high = n;//while循环的执行条件(low左指针要小于等于high右指针)while (low <= high) {/*** mid为使用二分法查找的中值* ----|-----|-----|---->* low mid high* |<-------->| mid ?* |<-------->|* high - low* |<--->|* (high-low)/2* |<-->|<--->|* low + (high-low)/2 = mid*/int mid = (high - low)/2 + low;/*** sum和为1到x之和, 即sum=1+2+3+4+..+x* 化简后为 1/2 * (x+1) * x = ((x+1) * x)/2*/int sum = ((mid + 1) * mid) /2;//判断sum(硬币之和)是否等于n(硬币总数)if (sum == n) {/*** 若sum(硬币之和)值等于n(硬币总数), 说明已经排列完毕* 则直接返回mid值, 此时mid值即为完成梯形排列的最后行数*/return mid;/*** 若sum(硬币之和)值大于n(硬币总数), 说明取值范围太大,* 因此将右指针high向左移动一位(即向上移动一行)*/} else if (sum > n) {//右指针high左移一位high = mid - 1;/*** 若sum(硬币之和)值小于n(硬币总数), 说明取值范围太小,* 因此将左指针low向右移动一位(即向下移动一行)*/} else {//左指针low右移一位low = mid + 1;}}//最后将high右指针值进行返回(此时high值为满足排列的总行数)return high;}}
- 测试结果
结果:测试结果与预期相同!
1.2.3 使用牛顿迭代法处理
1.解题思路
牛顿迭代公式:(x + n / x) / 2
需要满足的条件:(x + 1)x / 2 = n
我们将它进一步进行转化:
(x + 1) x = 2n => x * x + x = 2n => x * x = 2n - x
即x的平方等于2n减去x,x的平方相当于牛顿迭代公式中的n
我们只需将x的平方代入到上面的牛顿迭代公式中去,直到求出预期结果为止!
2.代码实现
- 测试代码
package com.kuang.leetcode9;/*** @ClassName ArrangeCoin* @Description 排列硬币* @Author 狂奔の蜗牛rz* @Date 2021/8/30*/
public class ArrangeCoin {//主方法测试public static void main(String[] args) {//测试存在10个硬币时,形成完整阶梯形状返回的总行数System.out.println("使用牛顿迭代法排列硬币:"+arrangeCoins3(10));}/*** 牛顿迭代求平方根* @param x 排列总行数(未知值)* @param n 硬币总个数(已知值)* @return*/private static double sqrt(double x, int n) {/*** 定义res返回结果值* 牛顿迭代公式: (x + n/x)/2* 满足条件代入: n = x * x = 2n - x* 即res值为(x + (2n -x)/x)/2*/double res = (x + (2 * n - x)/x)/2;//判断res(返回结果)值是否等于x(排列总行数)if (res == x) {//若满足条件, 则将x值返回(此时x值为满足条件的排列总行数)return x;} else {//若不满足条件, 则进行递归调用(将res结果值作为下一轮的x值)return sqrt(res, n);}}}
- 测试结果
结果:测试结果与预期相同!
好了,今天LeetCode每日一题—排列硬币到这里就结束了,欢迎大家学习和讨论,点赞和收藏!
参考视频链接:https://www.bilibili.com/video/BV1Ey4y1x7J3 (国内算法宝典-LeetCode算法50讲)
LeetCode每日一题之排列硬币相关推荐
- LeetCode 每日一题 42. 接雨水 详细多种题解 C++描述
LeetCode 每日一题 42. 接雨水 大家好,我叫亓官劼(qí guān jié ),在CSDN中记录学习的点滴历程,时光荏苒,未来可期,一起加油吧~ 难度 困难 2020.04.04每日一题 ...
- leetcode每日刷题计划-简单篇day8
leetcode每日刷题计划-简单篇day8 今天是纠结要不要新买手机的一天QAQ想了想还是算了吧,等自己赚钱买,加油 Num 70 爬楼梯 Climbing Stairs class Solutio ...
- Leetcode每日一题:171.excel-sheet-column-number(Excel表列序号)
思路:就是168题的反命题,进制的方式完美解决: Leetcode每日一题:168.excel-sheet-column-title(Excel表名称) class Solution {public: ...
- 【LeetCode每日一题】1723. 完成所有工作的最短时间
[LeetCode每日一题]1723. 完成所有工作的最短时间 [1] 1723. 完成所有工作的最短时间 [2] 473. 火柴拼正方形 [1] 1723. 完成所有工作的最短时间 题目: 给你一个 ...
- leetcode每日一题--雀巢原理;抽屉算法;Quorum机制;分布式应用
leetcode每日一题 539. 最小时间差 示例 1: 输入:timePoints = ["23:59","00:00"] 输出:1 示例 2: 输入:ti ...
- LeetCode每日一题——1812. 判断国际象棋棋盘中一个格子的颜色
LeetCode每日一题系列 题目:1812. 判断国际象棋棋盘中一个格子的颜色 难度:简单 文章目录 LeetCode每日一题系列 题目 示例 思路 题解 题目 给你一个坐标 coordinates ...
- 【LeetCode每日一题】——109.有序链表转换二叉搜索树
文章目录 一[题目类别] 二[题目难度] 三[题目编号] 四[题目描述] 五[题目示例] 六[题目提示] 七[解题思路] 八[时间频度] 九[代码实现] 十[提交结果] 一[题目类别] 二叉树 二[题 ...
- leetcode每日一题·救生艇问题(Python)
leetcode每日一题·救生艇问题(Python) 问题描述 题目入口 题目思路 首先分析问题,一个船最多坐两人,因此我们可以把这个问题看作两两组合的问题,并且如果最重的那个人和最轻的人加起来大于l ...
- LeetCode每日一题——904. 水果成篮
LeetCode每日一题系列 题目:904. 水果成篮 难度:普通 文章目录 LeetCode每日一题系列 题目 示例 思路 题解 题目 你正在探访一家农场,农场从左到右种植了一排果树.这些树用一个整 ...
最新文章
- 查看MS SQL Server数据库每个表占用的空间大小
- HTTPS协议,SSL协议及完整交互过程
- 单独组件_苹果已停止对macOS Big Sur 11.0.1版本macOS系统组件的单独更新
- 将自己写的经常复用的类封装成动态库的方法
- JavaScript中window对象属性,时间等的总结
- 【机器视觉】 endtry算子
- 【性能优化】 之 并行执行
- 量化交易,量化分析推荐书单
- 2020年有赞云生态发展白皮书
- SQL联合主键 查重
- Nginx学习总结(10)——Nginx前后端分离将多个请求转发到多个Tomcat,负载均衡反向代理
- Web前端笔记(1)
- 如何修改MySQL已有表的字符集
- 新鲜出炉的头条面试算法
- 体验下Xcode5与ios7
- 【OpenCV学习笔记】【函数学习】十六(Rect参数介绍)
- 廊坊金彩教育:店铺运营技巧思路
- 大疆FPGA/芯片开发工程师(A卷)笔试题(含详解)
- js银行卡、手机号等校验汇总
- 附录H-2 技术预研报告
热门文章
- Stream流中collect方法
- 百度惊雷算法3.0即将上线(终于开始整治SEO快排行业了)
- 基于人体姿势估计的舞蹈检测(AI Dance based on Human Pose Estimation)
- python全自动模拟_数十行 Python 代码全自动刷王者荣耀金币
- jdom编写xml自动缩进_2020学习python技巧资料之python缩进规则
- 计算机科学与技术班级口号八字,霸气八字班级口号_班级口号大全霸气十足
- 微软官网U启动制作工具安装window10系统
- MT6750详细芯片资料分享 MT6750设计原理图须知
- 域名的年龄对SEO影响有哪些?为什么老域名有利于SEO?
- MCE | 正确认识阿尔茨海默病