算法笔记:求1+2...+n


题目描述

此题目来自于剑指offer 64
题目描述:求 1+2+…+n ,要求不能使用乘除法、for、while、if、else、switch、case等关键字及条件判断语句(A?B:C)。
示例 1:
输入: n = 3
输出: 6
示例 2:
输入: n = 9
输出: 45
限制:
1 <= n <= 10000


思路

可以直接用小学学过的高斯公式:前n项和等于(首项+末项) * 项数 / 2

class Solution {
public:
    int sumNums(int n) {
        return (1 + n) * n / 2;
    }
};

但是由于题目要求不能使用乘除法所以此方案也不行。
所以我们可以使用math里面的库,或者使用递归等其他办法来解决。

使用pow

由于我们知道其答案就是n * (n + 1) / 2,拆解就是 (n ^ 2 + n) / 2
故可以使用

double pow(double x, double y);

这个函数返回x的y次幂,但是需要注意的一点是:pow返回的类型为double,然而函数需要返回int所以还需要强制类型转换才可。

class Solution {
public:
    int sumNums(int n) {
        return (int)(pow(n, 2) + n) >> 1;
    }
};

递归

运用条件表达式短路的性质:
A && B 如果A是false,B不执行
A || B 如果A是true,B不执行

class Solution {
public:
    int sumNums(int n) {
        int res = n;
        n && (res += sumNums(n - 1));
        return res;
    }
};

数组求大小

建立一个大小为 n * (n + 1)的数组,返回其大小的一般即可
代码如下(示例):

class Solution {
public:
    int sumNums(int n) {
        char res[n][n + 1];
        return sizeof(res) >> 1;
    }
};

静态成员变量实现累加

静态成员在类内声明,类外定义。
类中的所有成员共用一个静态成员变量。所以可以在构造函数中对其进行累加。
代码如下(示例):

class Temp {
public:
    static int sum;
    static int s;
    Temp() {
        ++s;
        sum += s;
    }
};

int Temp::sum = 0;
int Temp::s = 0;

class Solution {
public:
    int sumNums(int n) {
        vector<Temp> tmp(n);
        int res = Temp::sum;
        Temp::sum = 0;
        Temp::s = 0;
        return res;
    }
};

# 总结 这道题其实并不偏向算法,反而更偏向于语法一些。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
题目描述 有 $n$ 种不同面额的硬币,每种硬币的数量无限。假设硬币面额为 $a_1,a_2,...,a_n$,现在要用这些硬币来找零 $m$ 元,最少需要的硬币个数。 样例 输入:5,[1,2,5] 输出:2 算法1 (动态规划) $O(nm)$ 很明显,这是一道动态规划的问题。 设 $f[i][j]$ 为只考虑前 $i$ 种硬币,总面值为 $j$ 元时所需的最少硬币数。 显然,对于 $f[i][j]$,我们可以选择不取第 $i$ 种硬币,此时 $f[i][j]=f[i-1][j]$。也可以选择取第 $i$ 种硬币,此时 $f[i][j]=f[i][j-a_i]+1$。 于是,状态转移方程为: $$f[i][j]=\min(f[i-1][j],f[i][j-a_i]+1)$$ 注意,当 $j<a_i$ 时,显然不能取第 $i$ 种硬币,因此 $f[i][j]=f[i-1][j]$。 最终答案即为 $f[n][m]$。 时间复杂度 状态数为 $nm$,转移复杂度为 $O(1)$,故总时间复杂度为 $O(nm)$。 参考文献 无 C++ 代码 class Solution { public: int coinChange(vector<int>& coins, int amount) { int n = coins.size(); vector<vector<int>> f(n+1,vector<int>(amount+1,0x3f3f3f3f)); for(int i=0;i<=n;++i) f[i][0] = 0; for(int i=1;i<=n;++i){ for(int j=1;j<=amount;++j){ if(j<coins[i-1]) f[i][j] = f[i-1][j]; else f[i][j] = min(f[i-1][j],f[i][j-coins[i-1]]+1); } } return f[n][amount]>=0x3f3f3f3f?-1:f[n][amount]; } }; Java 代码 class Solution { public int coinChange(int[] coins, int amount) { int n = coins.length; int[][] f = new int[n+1][amount+1]; for(int i=0;i<=n;++i) f[i][0] = 0; for(int i=1;i<=n;++i){ for(int j=1;j<=amount;++j){ if(j<coins[i-1]) f[i][j] = f[i-1][j]; else f[i][j] = Math.min(f[i-1][j],f[i][j-coins[i-1]]+1); } } return f[n][amount]>=0x3f3f3f3f?-1:f[n][amount]; } }

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值