C#LeetCode刷题之#441-排列硬币(Arranging Coins)
问题
该文章的最新版本已迁移至个人博客【比特飞】,单击链接 https://www.byteflying.com/archives/3995 访问。
你总共有 n 枚硬币,你需要将它们摆成一个阶梯形状,第 k 行就必须正好有 k 枚硬币。
给定一个数字 n,找出可形成完整阶梯行的总行数。
n 是一个非负整数,并且在32位有符号整型的范围内。
n = 5
硬币可排列成以下几行:
¤
¤ ¤
¤ ¤因为第三行不完整,所以返回2.
n = 8
硬币可排列成以下几行:
¤
¤ ¤
¤ ¤ ¤
¤ ¤因为第四行不完整,所以返回3.
You have a total of n coins that you want to form in a staircase shape, where every k-th row must have exactly k coins.
Given n, find the total number of full staircase rows that can be formed.
n is a non-negative integer and fits within the range of a 32-bit signed integer.
n = 5
The coins can form the following rows:
¤
¤ ¤
¤ ¤Because the 3rd row is incomplete, we return 2.
n = 8
The coins can form the following rows:
¤
¤ ¤
¤ ¤ ¤
¤ ¤Because the 4th row is incomplete, we return 3.
示例
该文章的最新版本已迁移至个人博客【比特飞】,单击链接 https://www.byteflying.com/archives/3995 访问。
public class Program {
public static void Main(string[] args) {
var n = 8;
var res = ArrangeCoins(n);
Console.WriteLine(res);
n = 18;
res = ArrangeCoins2(n);
Console.WriteLine(res);
n = 28;
res = ArrangeCoins3(n);
Console.WriteLine(res);
n = 38;
res = ArrangeCoins4(n);
Console.WriteLine(res);
n = 58;
res = ArrangeCoins5(n);
Console.WriteLine(res);
n = 68;
res = ArrangeCoins6(n);
Console.WriteLine(res);
Console.ReadKey();
}
private static int ArrangeCoins(int n) {
//暴力解法,此解法LeetCode超时未AC
var res = 0;
var value = (long)0;
while(n > (value = ComputerT(++res))) { }
if(n != value) res--;
return res;
//以下解法同理,但 LeetCode 可以 AC
//if(n == 0) return 0;
//for(long i = 1; ; i++) {
// if(n >= (i + 1) * i / 2 && n < (i + 2) * (i + 1) / 2)
// return (int)i;
//}
}
private static int ComputerT(int n) {
//抽出来是为了让程序结构更清晰
return (1 + n) * n / 2;
}
private static int ArrangeCoins2(int n) {
//按1、2、3、4、5这样一直减下去
//直到n小于或等于0时为止
var index = 1;
while((n -= index++) > 0) { }
//考虑上述循环中因为是 index++
//index最终被多加了一次
//真实的索引应该是 index - 1
index--;
//小于0时,最后一排不完整,所以再减1
if(n < 0) return index - 1;
//等于0时,最后一徘正好完整
return index;
}
private static int ArrangeCoins3(int n) {
/* 推导过程
*
* 说明=>x ^ 2 表示 x 的平方
* 公式1:a ^ 2 + 2 * a * b + b ^ 2 = (a + b) ^ 2
* 公式2:公差为1的等差数列的求和公式为 S = (1 + n) * n / 2
*
* 推导=>
* 设在第 k 行硬币排完,那么
* (1 + k) * k / 2 = n
* 展开并两边同时乘以 2
* k + k ^ 2 = 2 * n
* 两边同时 + 0.25
* k ^ 2 + k + 0.25 = 2 * n + 0.25
* 合并
* (k + 0.5) ^ 2 = 2 * n + 0.25
* 两边同时开根号
* k + 0.5 = Math.Sqrt(2 * n + 0.25)
* 两边同时 - 0.5,求出 k 的值
* k = Math.Sqrt(2 * n + 0.25) - 0.5
*/
//原来的 n 为int,直接 2 * n + 0.25 会导致值溢出
//所以用 (long)n 强转
return (int)(Math.Sqrt(2 * (long)n + 0.25) - 0.5);
//以下解法同理,但换了一种求 k 的方式
//具体推导过程请看以下博文
//https://blog.csdn.net/zx2015216856/article/details/81950377
//return (int)((Math.Sqrt(8 * (long)n + 1) - 1) / 2);
}
private static int ArrangeCoins4(int n) {
//解法思路同ArrangeCoins
//都属于暴力求解,但此解法效率略高,可AC
var x = (long)n;
var temp = (long)n;
while(x * x + x > 2 * temp) {
x = (x * x + 2 * temp) / (2 * x + 1);
}
return (int)x;
}
private static int ArrangeCoins5(int n) {
//基本思路同ArrangeCoins和ArrangeCoins4
var k = (int)(Math.Sqrt(2) * Math.Sqrt(n));
return k * (k + 1) <= 2 * n ? k : k - 1;
}
private static int ArrangeCoins6(int n) {
//二分法
//二分是对暴力解法的优化
//使得循环更快的靠近目标
var left = 0L;
var right = (long)n;
while(left <= right) {
var mid = left + (right - left) / 2;
var sum = mid * (mid + 1) / 2;
if(sum > n) {
right = mid - 1;
} else {
left = mid + 1;
}
}
return (int)(left - 1);
}
}
以上给出6种算法实现,以下是这个案例的输出结果:
该文章的最新版本已迁移至个人博客【比特飞】,单击链接 https://www.byteflying.com/archives/3995 访问。
3
5
7
8
10
11
分析:
显而易见,ArrangeCoins、ArrangeCoins2、ArrangeCoins4、ArrangeCoins5的时间复杂度均为: ,ArrangeCoins3的时间复杂度基于 Math.Sqrt() 的实现,ArrangeCoins6的时间复杂度为:
。
C#LeetCode刷题之#441-排列硬币(Arranging Coins)的更多相关文章
- Leetcode之二分法专题-441. 排列硬币(Arranging Coins)
Leetcode之二分法专题-441. 排列硬币(Arranging Coins) 你总共有 n 枚硬币,你需要将它们摆成一个阶梯形状,第 k 行就必须正好有 k 枚硬币. 给定一个数字 n,找出可形 ...
- [Swift]LeetCode441. 排列硬币 | Arranging Coins
You have a total of n coins that you want to form in a staircase shape, where every k-th row must ha ...
- C#LeetCode刷题-二分查找
二分查找篇 # 题名 刷题 通过率 难度 4 两个排序数组的中位数 C#LeetCode刷题之#4-两个排序数组的中位数(Median of Two Sorted Arrays)-该题未达最优解 30 ...
- C#LeetCode刷题-数学
数学篇 # 题名 刷题 通过率 难度 2 两数相加 29.0% 中等 7 反转整数 C#LeetCode刷题之#7-反转整数(Reverse Integer) 28.6% 简单 8 字符串转整数 ...
- Java实现 LeetCode 441 排列硬币
441. 排列硬币 你总共有 n 枚硬币,你需要将它们摆成一个阶梯形状,第 k 行就必须正好有 k 枚硬币. 给定一个数字 n,找出可形成完整阶梯行的总行数. n 是一个非负整数,并且在32位有符号整 ...
- LeetCode刷题总结-数组篇(中)
本文接着上一篇文章<LeetCode刷题总结-数组篇(上)>,继续讲第二个常考问题:矩阵问题. 矩阵也可以称为二维数组.在LeetCode相关习题中,作者总结发现主要考点有:矩阵元素的遍历 ...
- LeetCode刷题总结-数组篇(下)
本期讲O(n)类型问题,共14题.3道简单题,9道中等题,2道困难题.数组篇共归纳总结了50题,本篇是数组篇的最后一篇.其他三个篇章可参考: LeetCode刷题总结-数组篇(上),子数组问题(共17 ...
- LeetCode刷题总结-树篇(上)
引子:刷题的过程可能是枯燥的,但程序员们的日常确不乏趣味.分享一则LeetCode上名为<打家劫舍 |||>题目的评论: 如有兴趣可以从此题为起点,去LeetCode开启刷题之 ...
- C#LeetCode刷题-动态规划
动态规划篇 # 题名 刷题 通过率 难度 5 最长回文子串 22.4% 中等 10 正则表达式匹配 18.8% 困难 32 最长有效括号 23.3% 困难 44 通配符匹配 17.7% ...
随机推荐
- java面试题jvm字节码的加载与卸载
虚拟机把描述类的数据从class文件加载到内存,并对数据进行校验,转换分析和初始化,最终形成可以被虚拟节直接使用的JAVA类型,这就是虚拟机的类加载机制. 类从被加载到虚拟机内存到卸载出内存的生命周期 ...
- 手把手教你安装Office 2019 for Mac ,安装包和破解码都给你准备好了,还装不上的话,你找我!
准备一个安装包,和一个破解工具 安装MicrosoftOffice16.23.19030902_Installer.pkg, 注意在断网情况下安装 同时不要自动更新 , 安装好之后不要打开文件! ...
- 消除win10桌面图标的右下方小箭头
很容易的小东西,在这里简单提一下 新建一个记事本,写下以下代码,改为.bat后缀,双击运行,然后箭头消失 reg add "HKEY_LOCAL_MACHINE\SOFTWARE\Micro ...
- 【JVM之内存与垃圾回收篇】方法区
方法区 前言 这次所讲述的是运行时数据区的最后一个部分 从线程共享与否的角度来看 ThreadLocal:如何保证多个线程在并发环境下的安全性?典型应用就是数据库连接管理,以及会话管理 栈.堆.方法区 ...
- 分布式 ID 解决方案之美团 Leaf
分布式 ID 在庞大复杂的分布式系统中,通常需要对海量数据进行唯一标识,随着数据日渐增长,对数据分库分表以后需要有一个唯一 ID 来标识一条数据,而数据库的自增 ID 显然不能满足需求,此时就需要有一 ...
- spring-cloud-alibaba-sentinel和feign配合使用,启动报Caused by: java.lang.AbstractMethodError: com.alibaba.cloud.sentinel.feign.SentinelContractHolder.parseAndValidateMetadata(Ljava/lang/Class;)Ljava/util/List
背景 我在学习spring-cloud-alibaba技术栈期间,在学习服务熔断与限流的时候,服务启动发生了以下异常 #这是控制台最上面的 sun.misc.Unsafe.park(Native Me ...
- spring学习(三)属性注入
用的是IDEA的maven工程,pom.xml文件导包依赖省略 本文主要写set方式注入 (一).一般类型注入 一.写两个实体类Car.User public class Car { private ...
- Python学习手册(第4版)PDF高清完整版免费下载|百度云盘
Python学习手册(第4版)PDF高清完整版免费下载|百度云盘 提取码:z6il 内容简介 Google和YouTube由于Python的高可适应性.易于维护以及适合于快速开发而采用它.如果你想要编 ...
- BUUCTF-Web Easy Calc
要素察觉 打开calc.php发现源码 过滤了很多字符.题目一开始提示了有waf,最后通过eval实现计算功能.考虑利用该函数读取flag文件,先尝试弹个phpinfo 被waf拦截,在num参数前面 ...
- 数据结构C语言实现----树
树的基本知识点 树的定义 树的ADT(抽象数据类型) 树的储存结构 二叉树的定义 二叉树的储存结构 遍历二叉树 二叉树的建立 二叉树的ADT typedef struct BiTNode { Elem ...