Date: 2019-08-08
1. 二叉树中和为某一值的路径 (考察知识点:树)
解释:
题目描述
输入一颗二叉树的根节点和一个整数,打印出二叉树中结点值的和为输入整数的所有路径。路径定义为从树的根结点开始往下一直到叶结点所经过的结点形成一条路径。(注意: 在返回值的list中,数组长度大的数组靠前)
# -*- coding:utf-8 -*-
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
def FindPath(self, root, expectNumber):
def subFindPath(root):
if root: # 如非空,则先放入缓存list:b
b.append(root.val)
# 若已到达叶子节点并且满足该路径的和等于预期的数字,则将b保存的缓存路径放入结果list:a
if not root.right and not root.left and sum(b) == expectNumber:
a.append(b[:])
else:
# 否则节点往左右孩子进行递归调用
subFindPath(root.left),subFindPath(root.right)
b.pop()# 如已到达叶子节点,无论满足与否,不断往上删除最后一个元素,递归其他孩子节点。
a, b = [], []
subFindPath(root)
return a
2.复杂链表的复制(考察知识点:链表) (未完全解决!!!)
题目描述
输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针指向任意一个节点),返回结果为复制后复杂链表的head。(注意,输出结果中请不要返回参数中的节点引用,否则判题程序会直接返回空)
注:此题比较难以思考,后续请多看!! 方法主要采取三步走的策略:复制原始链表的next指针,赋值原始链表的random指针,然后分离原始链表和复制的链表。
思路:
1. 把复制的结点链接在原始链表的每一对应结点后面
2. 把复制的结点的random指针指向被复制结点的random指针的下一个结点
3. 拆分成两个链表,奇数位置为原链表,偶数位置为复制链表,注意复制链表的最后一个结点的next指针不能跟原链表指向同一个空结点None,next指针要重新赋值None(判定程序会认定你没有完成复制)
# -*- coding:utf-8 -*-
class RandomListNode:
def __init__(self, x):
self.label = x#
self.next = None
self.random = None
class Solution:
# 返回 RandomListNode
def Clone(self, pHead):
if not pHead:
return None
dummy = pHead
# first step, N' to N next
while dummy:
dummynext = dummy.next
copynode = RandomListNode(dummy.label)
copynode.next = dummynext
dummy.next = copynode
dummy = dummynext
dummy = pHead
# second step, random' to random'
while dummy:
dummyrandom = dummy.random
copynode = dummy.next
if dummyrandom:
copynode.random = dummyrandom.next
dummy = copynode.next
# third step, split linked list
dummy = pHead
copyHead = pHead.next
while dummy:
copyNode = dummy.next
dummynext = copyNode.next
dummy.next = dummynext
if dummynext:
copyNode.next = dummynext.next
else:
copyNode.next = None
dummy = dummynext
return copyHead
另外一种思想:
# -*- coding:utf-8 -*-
# class RandomListNode:
# def __init__(self, x):
# self.label = x
# self.next = None
# self.random = None
class Solution:
# 返回 RandomListNode
def Clone(self, pHead):
# write code here
head = pHead
p_head = None
new_head = None
random_dic = {}
old_new_dic = {}
while head:
node = RandomListNode(head.label)
node.random = head.random
old_new_dic[id(head)] = id(node)
random_dic[id(node)] = node
head = head.next
if new_head:
new_head.next = node
new_head = new_head.next
else:
new_head = node
p_head = node
new_head = p_head
while new_head:
if new_head.random != None:
new_head.random = random_dic[old_new_dic[id(new_head.random)]]
new_head = new_head.next
return p_head
3. 二叉搜索树与双向链表 (考察知识:链表与树)
题目描述
输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表。要求不能创建任何新的结点,只能调整树中结点指针的指向。
本题需要将二叉搜索树转换为一个有序的双向链表:实际上就是一个中序遍历(左中右)的结果,只是需要将中序遍历的结果写成一个双向链表。
# -*- coding:utf-8 -*-
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
def __init__(self):
self.listHead = None
self.listTail = None
def Convert(self, pRootOfTree):
if pRootOfTree==None:
return
self.Convert(pRootOfTree.left) # 左子树遍历
# 以下部分是中间根节点的操作,包括初始节点
if self.listHead==None:
self.listHead = pRootOfTree
self.listTail = pRootOfTree
else:
self.listTail.right = pRootOfTree
pRootOfTree.left = self.listTail
self.listTail = pRootOfTree
self.Convert(pRootOfTree.right) # 右子树遍历
return self.listHead
参考一篇博文的详细解释:https://blog.csdn.net/u010005281/article/details/79657259,附上原文(建议回看这篇博客,python版本解释的非常到位!)。
4. 字符串的排列 (考察知识点:字符串+递归+动态规划)
题目描述
输入一个字符串,按字典序打印出该字符串中字符的所有排列。例如输入字符串abc,则打印出由字符a,b,c所能排列出来的所有字符串abc,acb,bac,bca,cab和cba。
输入描述:
输入一个字符串,长度不超过9(可能有字符重复),字符只包括大小写字母。
分析:实际上就是一个全排列,然后基于所有的全排列的结果去重+排序输出即可,
如果可以调用itertools库,可以如下超级简单操作:
# -*- coding:utf-8 -*-
import itertools
class Solution:
def Permutation(self, ss):
# write code here
if not ss:
return []
list_o = list(itertools.permutations(ss, len(ss)))
return sorted(list(set(list_o)))
# ss ='AabBc'
print(Permutation(ss))
[('A', 'B', 'a', 'b', 'c'), ('A', 'B', 'a', 'c', 'b'), ('A', 'B', 'b', 'a', 'c'), ('A', 'B', 'b', 'c', 'a'), ('A', 'B', 'c', 'a', 'b'), ('A', 'B', 'c', 'b', 'a'), ('A', 'a', 'B', 'b', 'c'), ('A', 'a', 'B', 'c', 'b'), ('A', 'a', 'b', 'B', 'c'), ('A', 'a', 'b', 'c', 'B'), ('A', 'a', 'c', 'B', 'b'), ('A', 'a', 'c', 'b', 'B'), ('A', 'b', 'B', 'a', 'c'), ('A', 'b', 'B', 'c', 'a'), ('A', 'b', 'a', 'B', 'c'), ('A', 'b', 'a', 'c', 'B'), ('A', 'b', 'c', 'B', 'a'), ('A', 'b', 'c', 'a', 'B'), ('A', 'c', 'B', 'a', 'b'), ('A', 'c', 'B', 'b', 'a'), ('A', 'c', 'a', 'B', 'b'), ('A', 'c', 'a', 'b', 'B'), ('A', 'c', 'b', 'B', 'a'), ('A', 'c', 'b', 'a', 'B'), ('B', 'A', 'a', 'b', 'c'), ('B', 'A', 'a', 'c', 'b'), ('B', 'A', 'b', 'a', 'c'), ('B', 'A', 'b', 'c', 'a'), ('B', 'A', 'c', 'a', 'b'), ('B', 'A', 'c', 'b', 'a'), ('B', 'a', 'A', 'b', 'c'), ('B', 'a', 'A', 'c', 'b'), ('B', 'a', 'b', 'A', 'c'), ('B', 'a', 'b', 'c', 'A'), ('B', 'a', 'c', 'A', 'b'), ('B', 'a', 'c', 'b', 'A'), ('B', 'b', 'A', 'a', 'c'), ('B', 'b', 'A', 'c', 'a'), ('B', 'b', 'a', 'A', 'c'), ('B', 'b', 'a', 'c', 'A'), ('B', 'b', 'c', 'A', 'a'), ('B', 'b', 'c', 'a', 'A'), ('B', 'c', 'A', 'a', 'b'), ('B', 'c', 'A', 'b', 'a'), ('B', 'c', 'a', 'A', 'b'), ('B', 'c', 'a', 'b', 'A'), ('B', 'c', 'b', 'A', 'a'), ('B', 'c', 'b', 'a', 'A'), ('a', 'A', 'B', 'b', 'c'), ('a', 'A', 'B', 'c', 'b'), ('a', 'A', 'b', 'B', 'c'), ('a', 'A', 'b', 'c', 'B'), ('a', 'A', 'c', 'B', 'b'), ('a', 'A', 'c', 'b', 'B'), ('a', 'B', 'A', 'b', 'c'), ('a', 'B', 'A', 'c', 'b'), ('a', 'B', 'b', 'A', 'c'), ('a', 'B', 'b', 'c', 'A'), ('a', 'B', 'c', 'A', 'b'), ('a', 'B', 'c', 'b', 'A'), ('a', 'b', 'A', 'B', 'c'), ('a', 'b', 'A', 'c', 'B'), ('a', 'b', 'B', 'A', 'c'), ('a', 'b', 'B', 'c', 'A'), ('a', 'b', 'c', 'A', 'B'), ('a', 'b', 'c', 'B', 'A'), ('a', 'c', 'A', 'B', 'b'), ('a', 'c', 'A', 'b', 'B'), ('a', 'c', 'B', 'A', 'b'), ('a', 'c', 'B', 'b', 'A'), ('a', 'c', 'b', 'A', 'B'), ('a', 'c', 'b', 'B', 'A'), ('b', 'A', 'B', 'a', 'c'), ('b', 'A', 'B', 'c', 'a'), ('b', 'A', 'a', 'B', 'c'), ('b', 'A', 'a', 'c', 'B'), ('b', 'A', 'c', 'B', 'a'), ('b', 'A', 'c', 'a', 'B'), ('b', 'B', 'A', 'a', 'c'), ('b', 'B', 'A', 'c', 'a'), ('b', 'B', 'a', 'A', 'c'), ('b', 'B', 'a', 'c', 'A'), ('b', 'B', 'c', 'A', 'a'), ('b', 'B', 'c', 'a', 'A'), ('b', 'a', 'A', 'B', 'c'), ('b', 'a', 'A', 'c', 'B'), ('b', 'a', 'B', 'A', 'c'), ('b', 'a', 'B', 'c', 'A'), ('b', 'a', 'c', 'A', 'B'), ('b', 'a', 'c', 'B', 'A'), ('b', 'c', 'A', 'B', 'a'), ('b', 'c', 'A', 'a', 'B'), ('b', 'c', 'B', 'A', 'a'), ('b', 'c', 'B', 'a', 'A'), ('b', 'c', 'a', 'A', 'B'), ('b', 'c', 'a', 'B', 'A'), ('c', 'A', 'B', 'a', 'b'), ('c', 'A', 'B', 'b', 'a'), ('c', 'A', 'a', 'B', 'b'), ('c', 'A', 'a', 'b', 'B'), ('c', 'A', 'b', 'B', 'a'), ('c', 'A', 'b', 'a', 'B'), ('c', 'B', 'A', 'a', 'b'), ('c', 'B', 'A', 'b', 'a'), ('c', 'B', 'a', 'A', 'b'), ('c', 'B', 'a', 'b', 'A'), ('c', 'B', 'b', 'A', 'a'), ('c', 'B', 'b', 'a', 'A'), ('c', 'a', 'A', 'B', 'b'), ('c', 'a', 'A', 'b', 'B'), ('c', 'a', 'B', 'A', 'b'), ('c', 'a', 'B', 'b', 'A'), ('c', 'a', 'b', 'A', 'B'), ('c', 'a', 'b', 'B', 'A'), ('c', 'b', 'A', 'B', 'a'), ('c', 'b', 'A', 'a', 'B'), ('c', 'b', 'B', 'A', 'a'), ('c', 'b', 'B', 'a', 'A'), ('c', 'b', 'a', 'A', 'B'), ('c', 'b', 'a', 'B', 'A')]
# 更简单的版本:(通过)
# -*- coding:utf-8 -*-
import itertools
class Solution:
def Permutation(self, ss):
# write code here
if not ss:
return []
return sorted(list(set(map(''.join, itertools.permutations(ss)))))
但是有时候面试时并不能调用该库,所以实际上考察的是全排列的写法:(递归思想)
# -*- coding:utf-8 -*-
class Solution:
def Permutation(self, ss):
if len(ss) <=0:
return []
res = list()
self.perm(ss,res,'')
uniq = list(set(res))
return sorted(uniq)
def perm(self,ss,res,path):
if ss=='':
res.append(path)
else:
for i in range(len(ss)):
self.perm(ss[:i]+ss[i+1:],res,path+ss[i])
5. 数组中出现次数超过一半的数字
题目描述
数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}。由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2。如果不存在则输出0。
思路:本题可以借用collections中的Counter库,其返回的是对于该字符串中每一个字符的频次统计的字典。然后计算出字符串长度的一半,然后比较字典中每一个字符的频次与长度半径,大于则输出;不存在大于则返回0.
# -*- coding:utf-8 -*-
import collections
class Solution:
def MoreThanHalfNum_Solution(self, numbers):
# write code here
if len(numbers)==0:
return 0
c = collections.Counter(numbers)
half = len(numbers)/2
for k, v in c.items():
if v > half:
return k
return 0