⭐算法入门⭐《二分枚举》简单08 —— LeetCode 441. 排列硬币

Posted 英雄哪里出来

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了⭐算法入门⭐《二分枚举》简单08 —— LeetCode 441. 排列硬币相关的知识,希望对你有一定的参考价值。

🔥让天下没有难学的算法🔥

C语言免费动漫教程,和我一起打卡!
🌞《光天化日学C语言》🌞

入门级C语言真题汇总
🧡《C语言入门100例》🧡

几张动图学会一种数据结构
🌳《画解数据结构》🌳

组团学习,抱团生长
🌌《算法入门指引》🌌

竞赛选手金典图文教程
💜《夜深人静写算法》💜

一、题目

1、题目描述

  你总共有 n n n 枚硬币,需要将它们摆成一个阶梯形状,第 k k k 行就必须正好有 k k k 枚硬币。给定一个数字 n n n,找出可形成完整阶梯行的总行数。 n n n 是一个非负整数,并且在 32位 有符号整型的范围内。
  样例输入: 2147483647
  样例输出: 65535

2、基础框架

  • C语言 版本给出的基础框架代码如下:
int arrangeCoins(int n){
}

3、原题链接

LeetCode 441. 排列硬币

二、解题报告

1、思路分析

  二分枚举答案,找到一个最大的 x x x,满足 x ( x + 1 ) 2 ≤ n u m \\frac {x(x+1)}{2} \\le num 2x(x+1)num,这里的 x x x 就是答案。注意加法和乘法的溢出,最简单的办法就是用long long

2、时间复杂度

  • 二分枚举答案,时间复杂度为 O ( l o g 2 n ) O(log_2n) O(log2n)

3、代码详解


#define ll long long
int arrangeCoins(int n){
    int l = 0, r = n;
    int mid;
    ll ans, mid2;
    while(l <= r) {
        mid = ((ll)l + r) >> 1;         // (1) 
        mid2 = (ll)mid * (mid+1) /2;    // (2) 
        if(mid2 <= n) {
            l = mid + 1;                // (3) 
            ans = mid;
        }else {
            r = mid - 1;                // (4) 
        }
    }
    return ans; 
}
  • ( 1 ) (1) (1) 确保加法不会溢出;
  • ( 2 ) (2) (2) 等差数列求和公式;
  • ( 3 ) (3) (3) 如果 m i d 2 ≤ n u m mid^2 \\le num mid2num,则 m i d mid mid 一定是一个可行解,并且最优解可能在 [ m i d + 1 , r ] [mid+1, r] [mid+1,r] 范围内;
  • ( 4 ) (4) (4) 否则,最优解可能出现在 [ l , m i d − 1 ] [l, mid-1] [l,mid1]

三、本题小知识

任何单调函数问题,都可以采用二分枚举进行求解。


以上是关于⭐算法入门⭐《二分枚举》简单08 —— LeetCode 441. 排列硬币的主要内容,如果未能解决你的问题,请参考以下文章

⭐算法入门⭐《二分枚举》简单05 —— LeetCode 1. 两数之和

⭐算法入门⭐《二分枚举》简单07 —— LeetCode 69. x 的平方根

⭐算法入门⭐《二分枚举》简单14 —— LeetCode LCP 28. 采购方案

⭐算法入门⭐《二分枚举》简单06 —— LeetCode 367. 有效的完全平方数

⭐算法入门⭐《二分枚举》简单12 —— LeetCode 374. 猜数字大小

⭐算法入门⭐《二分枚举》简单15 —— LeetCode LCP 18. 早餐组合