[解题报告]《算法零基础100讲》(第2讲) 数列

一、斐波那契数

力扣:509. 斐波那契数

题目描述

斐波那契数,通常用 F(n) 表示,形成的序列称为 斐波那契数列 。该数列由 01 开始,后面的每一项数字都是前面两项数字的和。

思路分析

f(0)=0,f(1)=1

f(n)=f(n-1)+f(n-2),其中n>1

通过递推来写

具体代码
class Solution {
    
    
public:
    int f[32];
    int fib(int n) {
    
    
        f[0]=0;f[1]=1;
        for(int i=2;i<=n;i++){
    
    
            f[i]=f[i-1]+f[i-2];
        }
        return f[n];
    }
};

二、第N个泰波那契数

力扣:1137.第N个泰波那契

题目描述

泰波那契序列 Tn 定义如下:

T0 = 0, T1 = 1, T2 = 1, 且在 n >= 0 的条件下 Tn+3 = Tn + Tn+1 + Tn+2

给你整数 n,请返回第 n 个泰波那契数 Tn 的值。

思路分析

根据递推公式,直接来

具体代码
class Solution {
    
    
public:
    int t[38];
    int tribonacci(int n) {
    
    
        t[0]=0;t[1]=1;t[2]=1;
        for(int i=3;i<=n;i++){
    
    
            t[i]=t[i-3]+t[i-2]+t[i-1];
        }
        return t[n];
    }
};

三、求1+2+3+…+n

力扣:剑指Offer 64.求1+2+3+…+n

题目描述

1+2+...+n ,要求不能使用乘除法。

思路分析

不能使用乘法,那就使用加法。通过递归计算即可。

具体代码
class Solution {
    
    
public:
    int sumNums(int n) {
    
    
        if(n==1)    return 1;
        return sumNums(n-1)+n;
    }
};

四、单调数列

力扣:896. 单调数列

题目描述

如果数组是单调递增或单调递减的,那么它是单调的。如果对于所有 i <= j,A[i] <= A[j],那么数组 A 是单调递增的。 如果对于所有 i <= j,A[i]> = A[j],那么数组 A 是单调递减的。当给定的数组 A 是单调数组时返回 true,否则返回 false。

思路分析

一次for循环遍历,若发现一次遍历时,同时满足前一个数比后面一个数大且后面一个数比前面一个数大(在一次循环遍历过程中),那么这个数列肯定不是单调的,返回false即可。否则返回true。

具体代码
class Solution {
    
    
public:
    bool isMonotonic(vector<int>& nums) {
    
    
        int n=nums.size();
        bool flag1=false;
        bool flag2=false;
        for(int i=1;i<n;i++){
    
    
            if(nums[i-1]<nums[i]){
    
    
                flag1=true;
            }
            if(nums[i-1]>nums[i]){
    
    
                flag2=true;
            }
        }
        return flag1&flag2?false:true;
    }
};

五、和为s的连续正数序列

力扣:剑指Offer 57- II.和为s的连续正数序列

题目描述

输入一个正整数 target ,输出所有和为 target 的连续正整数序列(至少含有两个数)。序列内的数字由小到大排列,不同序列按照首个数字从小到大排列。

思路分析

定义两个指针l,r。通过公式求解l到r之间的数的和是否等于target。若sum(l,r)>target,l++;sum(l,r)<target,r++;若相等且l与r不相等,则符合题意,保留。同时l++, r=(l+r)/2;

具体代码
class Solution {
    
    
public:
    int sum(int l,int r){
    
    
        return (l+r)*(r-l+1)/2;
    }
    vector<vector<int>> findContinuousSequence(int target) {
    
    
        vector<vector<int>> ans;
        int l=1,r=2;
        while(l<=target){
    
    
            if(sum(l,r)>target){
    
    
                l++;
            }else if(sum(l,r)<target){
    
    
                r++;
            }else{
    
    
                if(l!=r){
    
    
                    vector<int> a;
                    for(int i=l;i<=r;i++)  a.push_back(i);
                    ans.push_back(a);
                }
                l++;
                r=(l+r)/2;
            }
        }
        return ans;
    }
};

六、连续整数求和

力扣:829.连续整数求和

题目描述

给定一个正整数 N,试求有多少组连续正整数满足所有数字之和为 N?(1 <= N <= 10 ^ 9)

思路分析

根据N的范围,若直接暴力枚举会超时。O(N)的算法可能也会超时。

我们不妨设N=(x+1)+(x+2)+…(x+k),其中x>=0,k>=1。N=kx+k*(k+1)/2。我们可以化简得到x,

x=N/k-(k+1)/2;若x为整数则符合要求。因此枚我们可以通过枚举k,求x即可,判断x是否符合要求。

(因为2N=k(2x+k+1),又因为k<2x+k+1,所以k * k <2*N,来缩小k的范围))

具体代码
class Solution {
    
    
public:
    int consecutiveNumbersSum(int n) {
    
    
        int ans = 0;
        for(int k=1;k*k<2*n;k++){
    
    
            int x=n/k-(k+1)/2;
            if((2*x+k+1)*k==2*n){
    
    
                ans++;
            }
        }
        return ans;
    }
};

Guess you like

Origin blog.csdn.net/weixin_49393180/article/details/121879016