LeetCode 2485. Find the Pivot Integer【前缀和;枚举;数学;查表】简单

本文介绍了如何解决LeetCode上的中枢整数问题,提供了三种解法:枚举或前缀和、数学公式O(1)和查表O(1),并详细分析了每种方法的时间和空间复杂度。此外,还提到了与三角数和完全平方数的数学关联。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

本文属于「征服LeetCode」系列文章之一,这一系列正式开始于2021/08/12。由于LeetCode上部分题目有锁,本系列将至少持续到刷完所有无锁题之日为止;由于LeetCode还在不断地创建新题,本系列的终止日期可能是永远。在这一系列刷题文章中,我不仅会讲解多种解题思路及其优化,还会用多种编程语言实现题解,涉及到通用解法时更将归纳总结出相应的算法模板。

为了方便在PC上运行调试、分享代码文件,我还建立了相关的仓库:https://github.com/memcpy0/LeetCode-Conquest。在这一仓库中,你不仅可以看到LeetCode原题链接、题解代码、题解文章链接、同类题目归纳、通用解法总结等,还可以看到原题出现频率和相关企业等重要信息。如果有其他优选题解,还可以一同分享给他人。

由于本系列文章的内容随时可能发生更新变动,欢迎关注和收藏征服LeetCode系列文章目录一文以作备忘。

给你一个正整数 n ,找出满足下述条件的 中枢整数 x :

  • 1 和 x 之间的所有元素之和等于 x 和 n 之间所有元素之和。

返回中枢整数 x 。如果不存在中枢整数,则返回 -1 。题目保证对于给定的输入,至多存在一个中枢整数。

示例 1:

输入:n = 8
输出:6
解释:6 是中枢整数,因为 1 + 2 + 3 + 4 + 5 + 6 = 6 + 7 + 8 = 21

示例 2:

输入:n = 1
输出:1
解释:1 是中枢整数,因为 1 = 1

示例 3:

输入:n = 4
输出:-1
解释:可以证明不存在满足题目要求的整数。

提示:

  • 1 <= n <= 1000

解法1 枚举 或 前缀和

根据题意,我们从 1 1 1 开始遍历到 n n n ,并求前缀和,如果包含当前元素 x x x 的前缀和 s u m sum sum 等于 n × ( n + 1 ) / 2 − s u m + x n\times (n + 1) / 2 - sum + x n×(n+1)/2sum+x ,则说明当前元素 x x x 是中枢整数。

class Solution {
public:
    int pivotInteger(int n) {
        int sum = 0, tot = n * (n + 1) / 2;
        for (int x = 1; x <= n; ++x) {
            sum += x;
            if (sum == tot - sum + x) return x;
        }
        return -1;
    }
};

又或者,我们不用求前缀和,而是在 [ 1 , n ] [1,n] [1,n] 的范围内枚举 x x x ,判断以下等式是否成立。若成立,则 x x x 为中枢整数。
( 1 + x ) × x = ( x + n ) × ( n − x + 1 ) (1 + x) \times x = (x + n) \times (n - x + 1) (1+x)×x=(x+n)×(nx+1)

class Solution {
public:
    int pivotInteger(int n) {
        for (int x = 1; x <= n; ++x)
            if ((1 + x) * x == (x + n) * (n - x + 1))
                return x;
        return -1;
    }
};

复杂度分析:

  • 时间复杂度: O ( n ) O(n) O(n) ,其中 n n n 为给定的正整数 n n n
  • 空间复杂度: O ( 1 ) O(1) O(1)

解法2 数学O(1)

1 1 1 x x x 的元素和为 x ( x + 1 ) 2 \dfrac{x(x+1)}{2} 2x(x+1) x x x n n n 的元素和为 1 1 1 n n n 的元素和减去 1 1 1 x − 1 x-1 x1 的元素和,即 n ( n + 1 ) − x ( x − 1 ) 2 \dfrac{n(n+1)-x(x-1)}{2} 2n(n+1)x(x1) 。两式相等,简化后即

x = n ( n + 1 ) 2 x = \sqrt{\dfrac{n(n+1)}{2}} x=2n(n+1)

如果 x x x 不是整数则返回 − 1 −1 1

class Solution {
public:
    int pivotInteger(int n) {
        int m = n * (n + 1) / 2;
        int x = sqrt(m);
        return x * x == m ? x : -1;
    }
};

复杂度分析:

  • 时间复杂度: O ( 1 ) O(1) O(1) 。计算平方根有专门的 CPU 指令,可以视作是 O ( 1 ) O(1) O(1) 时间。Python 的 math.isqrt 用的牛顿迭代法,这里也视作 O ( 1 ) O(1) O(1)
  • 空间复杂度: O ( 1 ) O(1) O(1) ,仅用到若干变量。

解法3 查表O(1)

注意到 n ( n + 1 ) 2 \dfrac{n(n+1)}{2} 2n(n+1) 又叫三角数 triangular number(见 OEIS A000217),定义是:非负整数前 n n n 项和, 0 + 1 + 2 + … + n 0 + 1 + 2 + … + n 0+1+2++n 。如 0 , 1 , 3 , 6 , 10 , 15 , 21 , 28 , 36 , 45 , 55 , 66 , 78 , 91 , 105 , 120 , 136 , 153 , 171 , 190 , 210 , 231 , 253 , 276 , 300 , 325 , 351 , 378 , 406 , 435 , 465 , 496 , 528 , 561 , 595 , 630 , 666 , 703 , 741 , 780 , 820 , 861 , 903 , 946 , 990 , 1035 , 1081 , 1128 , 1176 , 1225 , 1275 , 1326 , 1378 , 1431 , … 0, 1, 3, 6, 10, 15, 21, 28, 36, 45, 55, 66, 78, 91, 105, 120, 136, 153, 171, 190, 210, 231, 253, 276, 300, 325, 351, 378, 406, 435, 465, 496, 528, 561, 595, 630, 666, 703, 741, 780, 820, 861, 903, 946, 990, 1035, 1081, 1128, 1176, 1225, 1275, 1326, 1378, 1431, … 0,1,3,6,10,15,21,28,36,45,55,66,78,91,105,120,136,153,171,190,210,231,253,276,300,325,351,378,406,435,465,496,528,561,595,630,666,703,741,780,820,861,903,946,990,1035,1081,1128,1176,1225,1275,1326,1378,1431, 帮助理解的方式:想像有一堆包子摆成杨辉三角的形状,前 n n n 行包子的数量之和就是第 n n n 个三角数。

一个三角数是完全平方数的情况(见 OEIS A001108),定义是:第 n n n 个(base 0)三角数同时是一个平方数。如 0 , 1 , 8 , 49 , 288 , 1681 , 9800 , 57121 , 332928 , 1940449 , 11309768 , 65918161 , 384199200 , … 0, 1, 8, 49, 288, 1681, 9800, 57121, 332928, 1940449, 11309768, 65918161, 384199200, … 0,1,8,49,288,1681,9800,57121,332928,1940449,11309768,65918161,384199200, 比如:

  • 1 1 1 个三角数是 1 1 1 ,它是 1 1 1 的平方
  • 8 8 8 个三角数, 8 × ( 8 + 1 ) / 2 = 36 8 \times (8 + 1) / 2 = 36 8×(8+1)/2=36 ,它是 6 6 6 的平方
  • 49 49 49 个三角数, 49 × ( 49 + 1 ) / 2 = 1225 49 \times (49 + 1) / 2 = 1225 49×(49+1)/2=1225 ,它是 35 35 35 的平方
  • 288 288 288 个三角数, 288 × ( 288 + 1 ) / 2 = 41616 288 \times (288 + 1) / 2 = 41616 288×(288+1)/2=41616 ,它是 204 204 204 的平方

一个数的平方数是三角数的情况(见 OEIS A001109)。如 0 , 1 , 6 , 35 , 204 , 1189 , 6930 , 40391 , 235416 , 1372105 , 7997214 , 46611179 , 271669860 , 1583407981 , … 0, 1, 6, 35, 204, 1189, 6930, 40391, 235416, 1372105, 7997214, 46611179, 271669860, 1583407981, … 0,1,6,35,204,1189,6930,40391,235416,1372105,7997214,46611179,271669860,1583407981, 比如:

  • 1 1 1 的平方 1 1 1 是三角数
  • 6 6 6 的平方 36 36 36 是三角数
  • 35 35 35 的平方 1225 1225 1225 是三角数
  • 204 204 204 的平方 41616 41616 41616 是三角数

即在本题数据范围下,这种「是三角数也是完全平方数的情况」是很少的。 n n n 只有 1 , 8 , 49 , 288 1,8,49,288 1,8,49,288
这四个,对应的答案为
1 , 6 , 35 , 204 1,6,35,204 1,6,35,204
上述数据用程序枚举 [ 1 , 1000 ] [1,1000] [1,1000] 内的 n n n ,调用上面的代码,即可得到。

class Solution {
    const unordered_map<int, int> m{{1, 1}, {8, 6}, {49, 35}, {288, 204}};
public:
    int pivotInteger(int n) {
        auto it = m.find(n);
        return it != m.end() ? it->second : -1;
    }
};

复杂度分析:

  • 时间复杂度: O ( 1 ) O(1) O(1)
  • 空间复杂度: O ( 1 ) O(1) O(1) ,仅用到若干变量。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

memcpy0

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值