剑指offer
二维数组中的查找
题目描述
在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。
python 解答代码:
# -*- coding:utf-8 -*-
class Solution:
# array 二维列表
def Find(self, target, array):
# write code here
row_n=len(array)
col_n=len(array[0])
for row in range(row_n-1,-1,-1):
for col in range(col_n):
if array[row][col]>target:
break
elif array[row][col]==target:
return True
return False
重建二叉树
题目描述
输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回。
思路:
分治法,前序首个元素是根结点,将序列分成两部分,用同样的方法递归处理子问题。注意递归的结束条件和返回值
python 解答代码:
# -*- 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
if not pre or not tin:
return None
pos=tin.index(pre[0])
root=TreeNode(pre[0])
root.left=self.reConstructBinaryTree(pre[1:pos+1],tin[:pos])
root.right=self.reConstructBinaryTree(pre[pos+1:],tin[pos+1:])
return root
从尾到头打印链表
题目描述
输入一个链表,从尾到头打印链表每个节点的值。
python 解答代码:
# -*- 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
re=[]
while listNode:
re.append(listNode.val)
listNode=listNode.next
return re[::-1]
替换空格
题目描述
请实现一个函数,将一个字符串中的空格替换成“%20”。例如,当字符串为We Are Happy.则经过替换之后的字符串为We%20Are%20Happy。
python 解答代码:
# -*- coding:utf-8 -*-
class Solution:
# s 源字符串
def replaceSpace(self, s):
# write code here
re=''
for si in s:
if si==' ':
re=re+'%20'
else:
re=re+si
return re
用两个栈实现队列
题目描述
用两个栈来实现一个队列,完成队列的Push和Pop操作。 队列中的元素为int类型。
python 解答代码:
# -*- coding:utf-8 -*-
class Solution:
def __init__(self):
self.stack1=[]
self.stack2=[]
def push(self, node):
# write code here
self.stack1.append(node)
def pop(self):
# return xx
if self.stack2:
return self.stack2.pop()
else:
while self.stack1:
self.stack2.append(self.stack1.pop())
return self.stack2.pop()
旋转数组的最小数字
题目描述
把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。输入一个非递减排序的数组的一个旋转,输出旋转数组的最小元素。例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,该数组的最小值为1。
NOTE:给出的所有元素都大于0,若数组大小为0,请返回0。
python 解答代码:
# -*- coding:utf-8 -*-
class Solution:
def minNumberInRotateArray(self, rotateArray):
# write code here
if not rotateArray:
return 0
le=len(rotateArray)
i_pre=0
for i in range(le):
if rotateArray[i]<rotateArray[i_pre]:
return rotateArray[i]
i_pre=i
return rotateArray[0]
斐波那契数列
题目描述
大家都知道斐波那契数列,现在要求输入一个整数n,请你输出斐波那契数列的第n项。n<=39
# -*- coding:utf-8 -*-
class Solution:
def Fibonacci(self, n):
# write code here
if n<=0:
return 0
if n==1 or n==2:
return 1
f1=1
f2=1
while n-2:
f3=f2+f1
f1=f2
f2=f3
n=n-1
return f3
台阶跳
题目描述
一只青蛙一次可以跳上1级台阶,也可以跳上2级。求该青蛙跳上一个n级的台阶总共有多少种跳法。
# -*- coding:utf-8 -*-
class Solution:
def jumpFloor(self, number):
# write code here
if number<=0:
return 0
if number==1:
return 1
if number==2:
return 2
f1=1
f2=2
while number-2:
f3=f2+f1
f1=f2
f2=f3
number=number-1
return f3
变态台阶跳
题目描述
一只青蛙一次可以跳上1级台阶,也可以跳上2级……它也可以跳上n级。求该青蛙跳上一个n级的台阶总共有多少种跳法。
# -*- coding:utf-8 -*-
class Solution:
def jumpFloorII(self, number):
# write code here
if number==1:
return 1
if number==2:
return 2
return 2**(number-1)
矩形覆盖
题目描述
我们可以用21的小矩形横着或者竖着去覆盖更大的矩形。请问用n个21的小矩形无重叠地覆盖一个2*n的大矩形,总共有多少种方法?
# -*- coding:utf-8 -*-
class Solution:
def rectCover(self, number):
# write code here
if number==0:
return 0
if number==1:
return 1
if number==2:
return 2
f1=1
f2=2
i=2
while i<number:
f3=f1+f2
f1=f2
f2=f3
i=i+1
return f3
二进制数中1的个数
题目描述
输入一个整数,输出该数二进制表示中1的个数。其中负数用补码表示。
(在python中,正数右移高位补0,负数右移高位补1,移位到最后,正数变为0,负数变为1)
# -*- coding:utf-8 -*-
class Solution:
def NumberOf1(self, n):
# write code here
re=0
for i in range(0,32):
if n>>i&1:
re+=1
return re
# -*- coding:utf-8 -*-
class Solution:
def NumberOf1(self, n):
# write code here
if n<0:
n=2**32+n
re=0
while n:
if n&1:
re+=1
n=n>>1
return re
数值的整数次方
题目描述
给定一个double类型的浮点数base和int类型的整数exponent。求base的exponent次方。
# -*- coding:utf-8 -*-
class Solution:
def Power(self, base, exponent):
# write code here
return base**exponent
# -*- coding:utf-8 -*-
class Solution:
def Power(self, base, exponent):
# write code here
if exponent==1:
return base
elif exponent==0:
return 1
elif exponent<0:
flag=1
exponent*=-1
else:
flag=0
i=1
re=1
while i<=exponent:
if exponent&i==i:
for _ in range(i):
re=re*base
i=i<<1
if flag==1:
return 1/re
else:
return re
调整数组顺序使奇数位于偶数前面
题目描述
输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有的奇数位于数组的前半部分,所有的偶数位于位于数组的后半部分,并保证奇数和奇数,偶数和偶数之间的相对位置不变。
# -*- coding:utf-8 -*-
class Solution:
def reOrderArray(self, array):
# write code here
a1=[]
a2=[]
for i in array:
if i%2:
a1.append(i)
else:
a2.append(i)
array=a1+a2
return array
# -*- coding:utf-8 -*-
class Solution:
def reOrderArray(self, array):
# write code here
p1=0
le=len(array)
for i in range(le):
for j in range(1,le-i):
if array[j-1]%2==0 and array[j]%2==1:
array[j-1],array[j]=array[j],array[j-1]
return array
链表中倒数第k个结点
题目描述
输入一个链表,输出该链表中倒数第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 not head:
return None
if k==0:
return None
p1=head
p2=head
for _ in range(k-1):
if p1.next:
p1=p1.next
else:
return None
while p1.next:
p2=p2.next
p1=p1.next
return p2
反转链表
题目描述
输入一个链表,反转链表后,输出链表的所有元素。
# -*- 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
tmp=[]
while pHead:
tmp.append(pHead.val)
pHead=pHead.next
if not tmp:
return None
head=ListNode(tmp.pop())
cur=head
while tmp:
cur.next=ListNode(tmp.pop())
cur=cur.next
return head
# -*- 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 not pHead:
return None
pre=None
while pHead:
# pre->head->next->...变成pre<-head next1->...
next=pHead.next
pHead.next=pre
pre=pHead
pHead=next
#当head为None时,pre为原来的最后一个节点,即是反转链表的第一个节点
return pre
合并两个排序的链表
题目描述
输入两个单调递增的链表,输出两个链表合成后的链表,当然我们需要合成后的链表满足单调不减规则。
非递归:
# -*- coding:utf-8 -*-
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
# 返回合并后列表
def Merge(self, pHead1, pHead2):
# write code here
head=ListNode(0)
tmp=head
while pHead1 and pHead2:
if pHead1.val<pHead2.val:
tmp.next=pHead1
pHead1=pHead1.next
else:
tmp.next=pHead2
pHead2=pHead2.next
tmp=tmp.next
while pHead1:
tmp.next=pHead1
pHead1=pHead1.next
tmp=tmp.next
while pHead2:
tmp.next=pHead2
pHead2=pHead2.next
tmp=tmp.next
return head.next
递归:
# -*- coding:utf-8 -*-
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
# 返回合并后列表
def Merge(self, pHead1, pHead2):
# write code here
if not pHead1:
return pHead2
elif not pHead2:
return pHead1
if pHead1.val<pHead2.val:
pHead1.next=self.Merge(pHead1.next,pHead2)
return pHead1
else:
pHead2.next=self.Merge(pHead1,pHead2.next)
return pHead2
树的子结构
题目描述
输入两棵二叉树A,B,判断B是不是A的子结构。(ps:我们约定空树不是任意一个树的子结构)
思路:递归检查根结点和左右子树是否满足条件,B可能是当前深度的子结构,也可能是下一个深度的子结构。
# -*- coding:utf-8 -*-
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
def HasSubtree(self, pRoot1, pRoot2):
if not pRoot1 or not pRoot2:
return False
return self.isSubtree(pRoot1,pRoot2)
def isSubtree(self,a,b):
if not b: #递归过程中,b为空,满足子结构条件
return True
elif not a: #递归过程中,a为空,不满足子结构条件
return False
elif a.val!=b.val: #值不相等,不满足子结构条件
return False
elif a.val==b.val: #如果值相等
return (isSubtree(a.left,b.left) and isSubtree(a.right,b.right)) or isSubtree(a.left,b) or isSubtree(a.right,b)
二叉树镜像
# -*- coding:utf-8 -*-
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
# 返回镜像树的根节点
def Mirror(self, root):
# write code here
if not root:
return root
root.left,root.right=self.Mirror(root.right),self.Mirror(root.left)
return root
顺时针打印矩阵
题目描述
输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字,例如,如果输入如下矩阵: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 则依次打印出数字1,2,3,4,8,12,16,15,14,13,9,5,6,7,11,10.
# -*- coding:utf-8 -*-
class Solution:
# matrix类型为二维列表,需要返回列表
def printMatrix(self, matrix):
# write code here
re=[]
flag=1
while matrix:
if flag==1:
re.extend(matrix.pop(0))
flag=2
elif flag==2:
row=len(matrix)
col=len(matrix[0])
for i in range(row):
re.append(matrix[i].pop(-1))
if col==1:
for i in range(row):
matrix.pop()
flag=3
elif flag==3:
re.extend(matrix.pop(-1)[::-1])
flag=4
else:
row=len(matrix)
col=len(matrix[0])
for i in range(row-1,-1,-1):
re.append(matrix[i].pop(0))
if col==1:
for i in range(row):
matrix.pop()
flag=1
return re
包含min函数的栈
题目描述
定义栈的数据结构,请在该类型中实现一个能够得到栈最小元素的min函数。
# -*- coding:utf-8 -*-
# 定义两个栈,一个保存元素,一个保存以当前元素为栈顶的子栈的最小元素
class Solution:
def __init__(self):
self.stack=[]
self.minstack=[]
def push(self, node):
# write code here
if not self.minstack:
self.minstack.append(node)
elif(node<self.minstack[-1]):
self.minstack.append(node)
self.stack.append(node)
def pop(self):
# write code here
tmp = self.stack.pop()
if tmp==self.minstack[-1]:
self.minstack.pop()
return tmp
def top(self):
# write code here
return self.stack[-1]
def min(self):
# write code here
return self.minstack[-1]
栈的压入、弹出序列
题目描述
输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否为该栈的弹出顺序。假设压入栈的所有数字均不相等。例如序列1,2,3,4,5是某栈的压入顺序,序列4,5,3,2,1是该压栈序列对应的一个弹出序列,但4,3,5,1,2就不可能是该压栈序列的弹出序列。(注意:这两个序列的长度是相等的)
# -*- coding:utf-8 -*-
class Solution:
def IsPopOrder(self, pushV, popV):
# write code here
tmp=[]
for i in pushV:
tmp.append(i)
while len(tmp) and tmp[-1]==popV[0]:
popV.pop(0)
tmp.pop()
if len(tmp):
return False
else:
return True
return False if len(tmp) else True
从上往下打印二叉树
题目描述
从上往下打印出二叉树的每个节点,同层节点从左至右打印。
# -*- coding:utf-8 -*-
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
# 返回从上到下每个节点值列表,例:[1,2,3]
def PrintFromTopToBottom(self, root):
if root is None:
return []
last_list = [root]
this_list = []
ans = []
while 1:
for node in last_list:
ans.append(node.val)
if node.left:
this_list.append(node.left)
if node.right:
this_list.append(node.right)
if len(this_list)==0:
break
last_list = this_list
this_list = []
return ans
二叉树的下一个结点
题目描述
给定一个二叉树和其中的一个结点,请找出中序遍历顺序的下一个结点并且返回。注意,树中的结点不仅包含左右子结点,同时包含指向父结点的指针。
# -*- coding:utf-8 -*-
# class TreeLinkNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
# self.next = None
class Solution:
def GetNext(self, pNode):
if pNode is None:
return None
if pNode.right is not None:
pNode = pNode.right
while pNode.left is not None:
pNode = pNode.left
return pNode
while pNode.next:
root = pNode.next
if pNode == root.left:
return root
else:
pNode = pNode.next
return None