爬台阶
假设你正在爬楼梯。需要 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;
}