问题

该文章的最新版本已迁移至个人博客【比特飞】,单击链接 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)的更多相关文章

  1. Leetcode之二分法专题-441. 排列硬币(Arranging Coins)

    Leetcode之二分法专题-441. 排列硬币(Arranging Coins) 你总共有 n 枚硬币,你需要将它们摆成一个阶梯形状,第 k 行就必须正好有 k 枚硬币. 给定一个数字 n,找出可形 ...

  2. [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 ...

  3. C#LeetCode刷题-二分查找​​​​​​​

    二分查找篇 # 题名 刷题 通过率 难度 4 两个排序数组的中位数 C#LeetCode刷题之#4-两个排序数组的中位数(Median of Two Sorted Arrays)-该题未达最优解 30 ...

  4. C#LeetCode刷题-数学

    数学篇 # 题名 刷题 通过率 难度 2 两数相加   29.0% 中等 7 反转整数 C#LeetCode刷题之#7-反转整数(Reverse Integer) 28.6% 简单 8 字符串转整数 ...

  5. Java实现 LeetCode 441 排列硬币

    441. 排列硬币 你总共有 n 枚硬币,你需要将它们摆成一个阶梯形状,第 k 行就必须正好有 k 枚硬币. 给定一个数字 n,找出可形成完整阶梯行的总行数. n 是一个非负整数,并且在32位有符号整 ...

  6. LeetCode刷题总结-数组篇(中)

    本文接着上一篇文章<LeetCode刷题总结-数组篇(上)>,继续讲第二个常考问题:矩阵问题. 矩阵也可以称为二维数组.在LeetCode相关习题中,作者总结发现主要考点有:矩阵元素的遍历 ...

  7. LeetCode刷题总结-数组篇(下)

    本期讲O(n)类型问题,共14题.3道简单题,9道中等题,2道困难题.数组篇共归纳总结了50题,本篇是数组篇的最后一篇.其他三个篇章可参考: LeetCode刷题总结-数组篇(上),子数组问题(共17 ...

  8. LeetCode刷题总结-树篇(上)

          引子:刷题的过程可能是枯燥的,但程序员们的日常确不乏趣味.分享一则LeetCode上名为<打家劫舍 |||>题目的评论: 如有兴趣可以从此题为起点,去LeetCode开启刷题之 ...

  9. C#LeetCode刷题-动态规划

    动态规划篇 # 题名 刷题 通过率 难度 5 最长回文子串   22.4% 中等 10 正则表达式匹配   18.8% 困难 32 最长有效括号   23.3% 困难 44 通配符匹配   17.7% ...

随机推荐

  1. three.js 绘制3d地图

    通过地图数据配合three可以做出非常酷炫的地图,在大数据展示中十分常见. 这篇郭先生就来说说使用three.js几何体制作3D地图.在线案例点击原文地址. 地图的数据是各个地图块的点数组,通过THR ...

  2. Mesos+Zookeeper+Marathon+Docker环境搭建

    相关理论请参考:https://www.cnblogs.com/Bourbon-tian/p/7155054.html,本文基于https://www.cnblogs.com/Bourbon-tian ...

  3. EF中延迟加载的那些事

    延迟加载又称懒加载,通俗一点就是关联了一个对象,不用的时候不去查这个对象,当调用的时候再组织sql去查出这个对象的相关内容. 一.在使用EF时,我们会发现借助于框架生成的实体类中的的导航属性通常是标记 ...

  4. JAVA I/O基本操作

    JAVA I/O基本操作 JAVA文件操作 JAVA字节流 JAVA字符流 JAVA缓存流 JAVA对象流 JAVA数据流 本文主要借鉴以下博客和网站: how2j.cn 深入理解java中的I/O ...

  5. WPF 有缩放时显示线条的问题

    公司项目已经开发好几年了,用的WPF开发的,期间遇到好多问题,都是些小细节.很久没有写博客了,以后有时间还是需要写写博客啊!作为分享也好.记录也好,利人利己嘛. 今天主要说一下显示线条的问题,因为我们 ...

  6. [翻译]ASP.NET Core在 .NET 5 Preview 7的更新

    .NET 5 Preview 7现在可以用了,可以进行评估了.这是此版本中的新增功能: Blazor WebAssembly应用程序现在针对.NET 5 更新了Blazor WebAssembly的调 ...

  7. for循环实现Fibonacci数列

    Fibonacci数列的递推公式为:Fn=Fn-1+Fn-2,其中F1=F2=1. 当n比较大时,Fn也非常大,现在我们想知道,Fn除以10007的余数是多少. 输入格式 输入包含一个整数n. 输出格 ...

  8. HTML自动刷新页面

    <meta http-equiv="refresh"content="5"/> 英文""

  9. 移动端rem字体适配JS

    // 『REM』手机屏幕适配,兼容更改过默认字体大小的安卓用户 function adapt(designWidth, rem2px) { // designWidth:'设计图宽度' 1rem==r ...

  10. flask的第一次尝试

    from flask import Flask app = Flask(__name__) @app.route('/') def hello_world(): return "Hello ...