问题

该文章的最新版本已迁移至个人博客【比特飞】,单击链接 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. 阿里面试官:这些软件测试面试题都答对了,I want you!

    [ 你悄悄来,请记得带走一丝云彩 ] 测试岗必知必会 01请描述如何划分缺陷与错误严重性和优先级别? 给软件缺陷与错误划分严重性和优先级的通用原则: 1. 表示软件缺陷所造成的危害和恶劣程度. 2. ...

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

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

  3. Ethical Hacking - Web Penetration Testing(8)

    SQL INJECTION WHAT IS SQL? Most websites use a database to store data. Most data stored in it(userna ...

  4. Python Ethical Hacking - BACKDOORS(5)

    File Download: A file is a series of characters. Therefore to transfer a file we need to: 1. Read th ...

  5. ASP.Net Core 3.1 With Autofac ConfigureServices returning an System.IServiceProvider isn't supported.

    ASP.Net Core 3.1 With Autofac ConfigureServices returning an System.IServiceProvider isn't supported ...

  6. k8s(00)入门知识介绍

    系列文章说明 本系列文章,可以基本算是 老男孩2019年王硕的K8S周末班课程 笔记,根据视频来看本笔记最好,否则有些地方会看不明白 需要视频可以联系我 k8s概念入门 目录 系列文章说明 k8s概念 ...

  7. Shell基本语法---for语句

    for语句 格式 ()for 变量名 in 值1 值2 值3 do 执行动作 done ()for 变量名 in `命令` do 执行动作 done ()for (( 条件 )) do 执行动作 do ...

  8. three.js 数学方法之Plane

    今天郭先生就来继续说一说three.js数学方法中的plane(平面).在三维空间中无限延伸的二维平面,平面方程用单位长度的法向量和常数表示.构造器为Plane( normal : Vector3, ...

  9. Redis集群搭建(哨兵)

    最近工作中需要用到redis哨兵集群,笔者自己搭建了3遍,直接开始 环境: 1,系统环境 系统 版本 操作系统 CentOS 7.4 Redis 5.0.8 2,IP请修改成自己的IP redis I ...

  10. ElasticSearch(一)概念介绍及环境搭建

    一.什么是ElasticSearch: Elasticsearch (ES)是一个基于Lucene构建的开源.分布式.RESTful 接口全文搜索引擎.Elasticsearch 还是一个分布式文档数 ...