剑指offer 学习之路
斐波纳契数列
查找斐波纳契数列中第 N 个数。
所谓的斐波纳契数列是指:
前2个数是 0 和 1 。
第 i 个数是第 i-1 个数和第i-2 个数的和。
斐波纳契数列的前10个数字是:
0, 1, 1, 2, 3, 5, 8, 13, 21, 34 …
样例
样例 1:
输入: 1
输出: 0
样例解释:
返回斐波那契的第一个数字,是0.
样例 2:
输入: 2
输出: 1
样例解释:
返回斐波那契的第二个数字是1.
- 解法
- 递归
def fibonacci(n):
# write your code here
res = [0, 1]
for i in range(2, n):
res.append(res[i-1]+res[i-2])
return res[n-1]
- 使用 yield 生成器
def fibonacci(n):
# write your code here
def fab(max):
n,a,b=0,0,1
while n<max:
yield b
a,b=b,a+b
n=n+1
if n == 1:
return 0
else:
for i in fab(n-1):
out = i
return out
print(fibonacci(2))
青蛙跳台阶
题目描述
一只青蛙一次可以跳上1级台阶,也可以跳上2级。求该青蛙跳上一个n级的台阶总共有多少种跳法(先后次序不同算不同的结果)。
class Solution:
def jumpFloor(self, number):
# write code here
if number == 1 or number == 2:
return number
jf = [1,2]
for i in range(number-2):
temp = jf[-1]+jf[-2]
jf.append(temp)
return jf[-1]
青蛙变态跳台阶
题目描述
一只青蛙一次可以跳上1级台阶,也可以跳上2级……它也可以跳上n级。求该青蛙跳上一个n级的台阶总共有多少种跳法。
- 解答:f(n)=2**(n-1)
# -*- coding:utf-8 -*-
class Solution:
def jumpFloorII(self, number):
# write code here
if number <= 0:
return 0
else:
return 2**(number-1)
二维数组中的查找
题目描述
在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。
class Solution:
# array 二维列表
def Find(self, target, array):
# write code here
row = len(array) - 1
col = len(array[0]) - 1
i = row
j = 0
while j<=col and i>=0:
if target<array[i][j]:
i = i - 1
elif target>array[i][j]:
j = j + 1
else:
return True
return False
替换空格
请实现一个函数,将一个字符串中的每个空格替换成“%20”。例如,当字符串为We Are Happy.则经过替换之后的字符串为We%20Are%20Happy
class Solution:
# s 源字符串
def replaceSpace(self, s):
# write code here
space = s.split(" ")
length = len(space)
string = str(space[0])
for i in range(1,length):
string = string + "%20" + str(space[i])
return string
- 更简单解法
class Solution:
# s 源字符串
def replaceSpace(self, s):
return s.replace(' ','%20')
从尾到头打印链表
输入一个链表,按链表值从尾到头的顺序返回一个ArrayList。
# -*- coding:utf-8 -*-
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
# 返回从尾部到头部的列表值序列,例如[1,2,3]
def printListFromTailToHead(self, listNode):
# write code here
array = []
if listNode is None:
return array
while listNode.next is not None:
array.append(listNode.val)
listNode = listNode.next
array.append(listNode.val)
return array[::-1] # 逆序
重建二叉树
题目描述
输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回。
# -*- coding:utf-8 -*-
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
# 返回构造的TreeNode根节点
def reConstructBinaryTree(self, pre, tin):
# write code here
lon = len(pre)
if lon == 0:
return None
elif lon == 1:
return TreeNode(pre[0])
else:
root = TreeNode(pre[0])
#这一步看似稍微写的有点复杂,但其实只是省了一些中间变量,pre[0]是读取的根节点,tin.index将根节点定位,那么根节点的左子树从1开始,到tin.index+1结束,建议自己在纸上将这部分框出来,就好理解的多了。
root.left = self.reConstructBinaryTree(pre[1:tin.index(pre[0])+1],tin[:tin.index(pre[0])])
root.right = self.reConstructBinaryTree(pre[tin.index(pre[0])+1:],tin[tin.index(pre[0])+1:])
return root
用两个栈实现队列
题目描述
用两个栈来实现一个队列,完成队列的Push和Pop操作。 队列中的元素为int类型。
思路:
事先说明这个信息:入栈时数据存入栈stackIn, 出栈时数据从stackOut弹出。执行入栈操作时,将数据源源不断的压入栈stackIn;执行出栈操作时,将stackIn的数据一次性全部弹出,存入到stackOut中。当stackOut栈非空时,不断弹出stackOut栈中的数据顺序即为队列的Pop顺序;当stackOut中的数据为空后,再将新入栈stackIn的数据一次性存入stackOut中即可。
class Solution:
def __init__(self):
self.stackin = []
self.stackout = []
def push(self, node):
# write code here
self.stackin.append(node)
def pop(self):
# return xx
if self.stackout:
return self.stackout.pop()
else:
while self.stackin:
self.stackout.append(self.stackin.pop())
return self.stackout.pop()
旋转数组的最小数字
题目描述
把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。 输入一个非减排序的数组的一个旋转,输出旋转数组的最小元素。 例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,该数组的最小值为1。 NOTE:给出的所有元素都大于0,若数组大小为0,请返回0。
- 解法1:排序
class Solution:
def minNumberInRotateArray(self, rotateArray):
# write code here
if not rotateArray:
return 0
else:
new_array = sorted(rotateArray)
return new_array[0]
- 解法2:二分查找
# -*- coding:utf-8 -*-
class Solution:
def minNumberInRotateArray(self, rotateArray):
# write code here
length = len(rotateArray)
if length == 0:
return 0
elif length == 1:
return rotateArray[0]
else:
left = 0
right = length - 1
while left < right:
mid = int((left + right)/2)
if rotateArray[mid] < rotateArray[right]:
right = mid
else:
left = mid+1
return rotateArray[left]
矩阵覆盖
题目描述
我们可以用21的小矩形横着或者竖着去覆盖更大的矩形。请问用n个21的小矩形无重叠地覆盖一个2*n的大矩形,总共有多少种方法
# -*- coding:utf-8 -*-
class Solution:
def rectCover(self, number):
# write code here
if number == 1 or number == 2 or number==0:
return number
else:
first = 1
second = 2
for i in range(number-2):
temp = first + second
first = second
second = temp
return temp
二进制中1的个数
题目描述
输入一个整数,输出该数二进制表示中1的个数。其中负数用补码表示。
[+1] = [00000001]原 = [00000001]反 = [00000001]补
[-1] = [10000001]原 = [11111110]反 = [11111111]补
class Solution:
def NumberOf1(self, n):
# write code here
count = 0
if n < 0:
n = n & 0xffffffff
while n:
count += 1
n = (n - 1) & n
return count
数值的整数次方
题目描述
给定一个double类型的浮点数base和int类型的整数exponent。求base的exponent次方。
- 偷波懒
# -*- coding:utf-8 -*-
class Solution:
def Power(self, base, exponent):
# write code here
if exponent == 0:
return 1
else:
return base**exponent
调整数组顺序使奇数位于偶数前面
题目描述
输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有的奇数位于数组的前半部分,所有的偶数位于数组的后半部分,并保证奇数和奇数,偶数和偶数之间的相对位置不变。
# -*- coding:utf-8 -*-
class Solution:
def reOrderArray(self, array):
# write code here
odd = []
even = []
if len(array)==1:
return array
for i in array:
if i % 2 == 1:
odd.append(i)
else:
even.append(i)
return odd+even
链表中倒数第k个结点
题目描述
输入一个链表,输出该链表中倒数第k个结点。
- 解法
p1,p2,先让p2走k-1步,然后再一起走,直到p2为最后一个 时,p1即为倒数第k个节点
# -*- coding:utf-8 -*-
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
def FindKthToTail(self, head, k):
# write code here
if head==None or k<=0:
return None
p2=head
p1=head
for i in range(k-1):
if p2.next!=None:
p2=p2.next
else:
return None
while p2.next!=None:
p1=p1.next
p2=p2.next
return p1
反转链表
题目描述
输入一个链表,反转链表后,输出新链表的表头。
# -*- coding:utf-8 -*-
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
# 返回ListNode
def ReverseList(self, pHead):
# write code here
if pHead==None or pHead.next==None:
return pHead
cur = pHead
pre = None
while cur != None:
temp = cur.next
cur.next = pre
pre = cur
cur = temp
return pre