25.输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针指向任意一个节点),返回结果为复制后复杂链表的head。(注意,输出结果中请不要返回参数中的节点引用,否则判题程序会直接返回空)
方法一:也算是最普遍的算法,分两次复制;
class Solution:
# 返回 RandomListNode
def Clone(self, pHead):
# write code here
# 复制原链表,组合成新链表
if not pHead:
return None
cloNode = pHead
while cloNode:
# 创建新节点
node = RandomListNode(cloNode.label)
node.next = cloNode.next
# 将新节点赋值给cloNode的下一个节点,等到拆分时,第一次赋值的节点相当于头
cloNode.next = node
# 将头节点指向原链表的下一项
cloNode = node.next
# 将指针从新指向头,为复制随机指针作准备
cloNode = pHead
# 复制原链表中的随机指针
while cloNode:
node = cloNode.next
# 若是有随机指针就进行复制
if cloNode.random:
node.random = cloNode.random.next
# 向后移动1位,此时相当于移动了2位
cloNode = node.next
cloNode = pHead
pHead = cloNode.next
# 拆分链表
while cloNode:
node = cloNode.next
cloNode = node.next
if cloNode is None:
break
node.next = cloNode.next
# 返回头,此时头已经指向第二个了
return pHead
方法二:递归
def Clone(self, pHead):
# write code here
if not pHead: return
newNode = RandomListNode(pHead.label)
newNode.random = pHead.random
newNode.next = self.Clone(pHead.next)
return newNode
方法三:深度复制
26输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表。要求不能创建任何新的结点,只能调整树中结点指针的指向。
class Solution:
def Convert(self, pRootOfTree):
# write code here
if pRootOfTree is None:
return None
self.linklast = None # 用于保存递归中最后一个节点
self.conver(pRootOfTree)
phead = self.linklast
# 循环进行左连接
while phead and phead.left:
phead = phead.left
return phead
# 递归中序遍历二叉搜索树
def conver_node(self, root):
if not root:return
pcurr = root # 保存当前节点
if pcurr.left:
self.conver(pcurr.left)
pcurr.left = self.linklast
# 将上个节点right指向下个中序遍历的节点
if self.linklast:
self.linklast.right = pcurr
# 同步指向的节点,相当于指向最新的中序结果
self.linklast = pcurr
if pcurr.right:
self.conver(pcurr.right)
27.输入一个字符串,按字典序打印出该字符串中字符的所有排列。例如输入字符串abc,则打印出由字符a,b,c所能排列出来的所有字符串abc,acb,bac,bca,cab和cba。通过递归实现多重for循环,参考自牛客网杨少
class Solution:
def Permutation(self, ss):
# write code here
# ''并不等于空
if len(ss) <= 0:
return []
# 用于存取组合结果
res = list()
self.perm(ss, res, '')
# 通过set()进行去重
res = list(set(res))
# 通过sorted进行排序
return sorted(res)
def perm(self, ss, res, path):
# 递归结束条件,当ss为‘’,时说明path已经组合完了
if ss == '':
# 将递归结果添加到path中
res.append(path)
else:
# 对ss进行循环,每次递归ss长度都减少1
for i in range(len(ss)):
# ss[:i]+ss[i+1:] 相当于是从ss中选择第i个添加到path中
self.perm(ss[:i] + ss[i+1:], res, path + ss[i])
28.数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}。由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2。如果不存在则输出0。
通过第一次循环统计每个数出现的次数,第二次循环找出出现次数大于数组长度一半的值。
class Solution:
def MoreThanHalfNum_Solution(self, numbers):
# write code here
dic = dict()
# 统计每个数出现的次数
for i in numbers:
if i not in dic:
dic[i] = 0
dic[i] = dic[i]+1
length = len(numbers) // 2
# 找出出现次数大于一半的数
for i in dic:
if dic[i] > length:
return i
else:
return 0