1、旋转数组的最小值
题目描述:把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。 输入一个非减排序的数组的一个旋转,输出旋转数组的最小元素。 例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,该数组的最小值为1。 NOTE:给出的所有元素都大于0,若数组大小为0,请返回0。
代码实现:
# -*- coding:utf-8 -*-
class Solution:
def minNumberInRotateArray(self, rotateArray):
# write code here
#if len(rotateArray)==0 or rotateArray[i: for i in range(len(rotateArray))]<=0:
#return False 应该是有这种写法的一句话了事,但是我语法不对,改为以下2个if
if len(rotateArray)==0:
return False
for i in range(len(rotateArray)):
if rotateArray[i]<=0:
return False
#for(i=0;i<len(rotateArray);i++): #python中好像没有这种写法?
i = 0
while i<len(rotateArray)-1:
if rotateArray[i]>rotateArray[i+1]:
return rotateArray[i+1]
else:
min = rotateArray[i]
i+=1
return min
旋转后的数组的特点是最小值前边的值一定比它大,后边的值也比它大,我们可以从前往后遍历,当发现有一个值比他后边的值大(原本是递增序的),那么后边的值一定是最小的,return此值。当然也有一种例外,就是所有的数字都旋转一遍,这样最小值还是在第一个,按上边的方法比较,不会出现某个值比它后边的值大的情况,这种我们需要记录过程中的最小值,到最后如果没有从第一个return返回,就在遍历完后return min。
2、斐波那契数列
题目描述:大家都知道斐波那契数列,现在要求输入一个整数n,请你输出斐波那契数列的第n项(从0开始,第0项为0)。
n<=39
代码实现:
# -*- coding:utf-8 -*-
class Solution:
def Fibonacci(self, n):
# write code here
#if n==0:
#return 0
#if n==1:
#return 1
#return Fibonacci(n-1)+Fibonacci(n-2)
#用循环迭代,用两个空间记录f(n-1)和f(n-2),不要使用递归,因为递归会有很多重复操作
if n==0:
return 0
if n==1 or n==2:
return 1
mem=[1,1]
for i in range(n-2):
mem.append(mem[-1]+mem[-2])
return mem[-1]
递归的本质是栈,容易导致栈溢出,所以不是不能用递归,只要能避免栈溢出,递归还是可以选择使用的。
尾递归的百科解释:
如果一个函数中所有递归形式的调用都出现在函数的末尾,我们称这个递归函数是尾递归的。当递归调用是整个函数体中最后执行的语句且它的返回值不属于表达式的一部分时,这个递归调用就是尾递归。尾递归函数的特点是在回归过程中不用做任何操作,这个特性很重要,因为大多数现代的编译器会利用这种特点自动生成优化的代码。
尾递归的原理:
当编译器检测到一个函数调用是尾递归的时候,它就覆盖当前的活动记录而不是在栈中去创建一个新的。编译器可以做到这点,因为递归调用是当前活跃期内最后一条待执行的语句,于是当这个调用返回时栈帧中并没有其他事情可做,因此也就没有保存栈帧的必要了。通过覆盖当前的栈帧而不是在其之上重新添加一个,这样所使用的栈空间就大大缩减了,这使得实际的运行效率会变得更高。
以下是一种尾递归的方法:
# -*- coding:utf-8 -*-
class Solution:
def Fibonacci(self, n):
#尾递归
a = 0
b = 1
val = self.f2(n,0,1) #self很重要
return val
def f2(self,n,a,b):
if n<0:
return 0
if n==0:
return a
if n==1:
return b
else:
return self.f2(n-1,b,a+b) #self很重要
3、跳台阶
题目描述:一只青蛙一次可以跳上1级台阶,也可以跳上2级。求该青蛙跳上一个n级的台阶总共有多少种跳法(先后次序不同算不同的结果)。
代码实现:
# -*- coding:utf-8 -*-
class Solution:
def jumpFloor(self, number):
# write code here
'''
跳台阶问题实际是看n分成1和2的方式有多少种,
n=1: 1 1=1
n=2: 2 2=1+1=2
n=3: 3 3=1+1=1=1+2=2+1
n=4: 5 4=1+1+1+1=1+1+2=1+2+1=2+1+1=2+2
...
'''
if number==1 or number==2:
return number
kinds = [1,2]
for i in range(number-2):
kinds.append(kinds[-1]+kinds[-2])
return kinds[-1]
与上边得斐波那契的迭代法类似。