1、二维数组的查找:
问题描述:在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。
代码实现:
# -*- coding:utf-8 -*-
class Solution:
# array 二维列表
'''
#从第一行第最后一列开始比较(右上角)
def Find(self, target, array):
# write code here
if len(array)==0 or len(array[0])==0:
return False
i=0
j=len(array[0])-1
while i<len(array) and j>=0:
if array[i][j]==target:
return True
elif array[i][j]<target:
i=i+1
else:
j=j-1
return False
'''
#第二种:从第最后一行第0列的位置开始比较(与第一种只是颠倒了i和j)
def Find(self, target, array):
if len(array)==0 or len(array[0])==0:
return False
i=len(array)-1
j=0
while i>=0 and j<len(array[0]):
if array[i][j]==target:
return True
elif array[i][j]<target:
j+=1
else:
i-=1
return False
第一次做剑指offer,一只知道二分查找的思想,就极少使用,参考着别人的回答和分析,做了此题。
此二维数组比较特殊,每行中右边的数比左边的数大,每列中下边的数比上边的数大。
将行号,列号比作平常所见的一维数据中的low,high,初始设置第0行第最后一列,mid的位置就是第0行第最后一列,将此位置的数与目标值比较;
比目标值大说明目标值在此位置的左上侧,列号减减;
比目标值小说明目标值在此位置的右下侧,行号加加;
如此查找。
第二种类似的方法也可以这样:
将行号,列号比作平常所见的一维数据中的high,low,初始设置第最后1行第一列,mid的位置就是第最后一行第一列,将此位置的数与目标值比较;
比目标值大说明目标值在此位置的左上侧,行号减减;
比目标值小说明目标值在此位置的右下侧,列号加加;
2、替换空格:
问题描述:请实现一个函数,将一个字符串中的每个空格替换成“%20”。例如,当字符串为We Are Happy.则经过替换之后的字符串为We%20Are%20Happy。
代码实现:
# -*- coding:utf-8 -*-
#import re
class Solution:
# s 源字符串
def replaceSpace(self, s):
# write code here
#1
#return re.sub(' ','%20',s)
#2
#return s.replace(' ','%20')
#3字符串是不可变对象,所以可以先变成list(暂时有问题)
s1=list(s)
length=len(s1)
for i in range(length-1,-1,-1):
if s1[i]==' ':
s=s+' '
s1.append(' ')
s1.append(' ')
length+=2
j=length-1
while (j-2)>i:
s1[j]=s[j-2]
j-=1
s1[i]='%'
s1[i+1]='2'
s1[i+2]='0'
s=''.join(s1)
return s
#4将旧字符串换到了新字符串
'''
str=''
for i in s:
if i==' ':
str=str+'%20'
else:
str=str+i
return str
'''
具体的解题思路是将字符串转换成list
列表的形式,主要是因为s作为字符串是不可变对象。
转换后的s是s1,从后往前比较,遇到空格就进行如下操作:
1s1
列表增加
2
个位置,长度加
2
,;
2
将遇到到空格后面的字母往后挪
2
个位置,并在空格位置及之后的两个位置填入
%
20
;
3
如此反复,直到遍历完成整个
list
;
4
比较次数时列表的长度,移动次数是
sum
(每个空格后面的元素个数)
5
最后把
list
形式的s1转化成string的s
3、从尾到头打印链表:
问题描述:
输入一个链表,按链表值从尾到头的顺序返回一个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
head=listNode
array=[]
while head is not None:
array.append(head.val)
head=head.next
array.reverse()
return array
主要是遍历整个链表,从头到尾,并把节点的值(val)赋给Arraylist,最后使用reverse()函数把整个
list
逆序一下。
4、重建二叉树
问题描述:
输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{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
if pre==[]:
return None
val=pre[0]
index=tin.index(val)
ltin=tin[0:index]
rtin=tin[index+1:]
lpre=pre[1:1+len(ltin)]
rpre=pre[1+len(ltin):]
root=TreeNode(val)
root.left=self.reConstructBinaryTree(lpre,ltin)
root.right=self.reConstructBinaryTree(rpre,rtin)
return root
主要是通过二叉树的前序和中序序列,构造二叉树。
首先根据二叉树的前序遍历中的第一个值知道二叉树的根节点(root),同时该节点将中序序列分成了左右子树;
然后再根据前序序列的第二个值知道左子树的根节点,同时将中序序列中的左子树又分为左右子树,以此类推直到将左边子树划分为完,再以同样的方式划分右子树,直到划分完;
最后输出节点值。
5、用2个栈实现队列
问题描述:用两个栈来实现一个队列,完成队列的Push和Pop操作。 队列中的元素为int类型。
代码实现:
# -*- 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 len(self.stack2):
return self.stack2.pop()
while self.stack1:
self.stack2.append(self.stack1.pop())
return self.stack2.pop()
队列的特点是先进先出,栈的特点是先进后出。
使用两个栈(先进后出)实现队列的先进先出的主要想法是:
push和pop分别通过不同的栈实现,Push的时候放进一个栈stack1中,pop时从另一个栈中出stack2,而stack1和stack2的关系是stack2的内容是从stack1中来的,stack1中栈底是最先进入的值,栈顶是最后进来的值,这样stack2中栈底的值就是最后进来的值,栈顶的值是最先进入的,从stack2中出栈便能得到最先进入的值。
通过两个栈的合作便能实现队列的功能,先进先出。
以上参考牛客网的剑指offer题目以及其他题友的分析。