爬台阶,Nim游戏,最大子序和问题

爬台阶

假设你正在爬楼梯。需要 n 阶你才能到达楼顶。每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢?
注意:给定 n 是一个正整数。
示例 1:输入: 2输出: 2
解释: 有两种方法可以爬到楼顶。
1 阶 + 1 阶;2 阶
示例 2:输入: 3输出: 3
解释: 有三种方法可以爬到楼顶。
1 阶 + 1 阶 + 1 阶;1 阶 + 2 阶;2 阶 + 1 阶

这个问题有两种思路:首先我们来看第一种递归解法:因为每次可以跳1阶或者2阶,所以每次跳完时,总台阶数-1或者-2;当台阶数为1时一共有1种跳法,两个台阶时有两种跳法;我们看具体的程序:

int climbStairs(int n) 
{
    if(n<=2){return n;}
    else
    {
        return climbStairs(n-1)+climbStairs(n-2);
    }
}

但我们发现,这样使用递归在台阶数变多之后,效率会飞速下降,这是因为每一次跳台阶我们都会有2个情况的分支,当需要递归n次时,程序就要进行21+… …2n这么多次的运算;同时我们发现,这里的情况分支是本项等于前一项和前二项的和,这不就是斐波那契数列吗?这就可以使用第二种方法:非递归实现:

int climbStairs(int n) 
{
     int a = 1,b = 2,c = 0;
    if(n<=2){return n;}
    else
    {
        for(int i = 3;i<=n;i++)
        {
            c = a+b;
            a = b;
            b = c;
        }
        return c;
    }
}
Nim游戏

你和你的朋友,两个人一起玩 Nim游戏:桌子上有一堆石头,每次你们轮流拿掉 1 - 3 块石头。 拿掉最后一块石头的人就是获胜者。你作为先手。编写一个函数,来判断你是否可以在给定石头数量的情况下赢得游戏。

从题目上我们可以得到一个重要信息:如果剩余的石头有4个,那麽我们无论如何也不会赢。因为我的朋友是也是个聪明人,他一定可以拿去剩下的所有石头;所以我们只需要判断石头的个数是不是4的倍数就可以了:

bool canWinNim(int n) 
{
    return n%4;
}//对就是只需一句话就能搞定=_=;
最大子序和

给定一个整数数组 nums ,找到一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。
示例:
输入: [-2,1,-3,4,-1,2,1,-5,4],输出: 6
解释: 连续子数组 [4,-1,2,1] 的和最大,为 6。

这里我们需要明白,具有最大和,那就说明我要加上的这个数是一个正数或者零,否则我就’亏了’,或者这个数是负数,但是这后面的数可以弥补我在这个数上的损失,所以每一次加上一个数,我都要和我之前的最大值判断一下,谁大取谁;
具体程序实现:

int maxSubArray(int* nums, int numsSize)
{
    int sum=0,i;
    int res=INT_MIN;
    for(i=0;i<numsSize;i++)
    {
        if(sum>=0)
            sum+=nums[i];
        else
            sum=nums[i];
        res=(sum>res)?sum:res;
    }
    return res;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值