有关ms100题中的python实现

##本部分来自july的微软面试的100题

########################################################################
##                    题1.二元查找树转化为双向链表                    ##
########################################################################
## 递归遍历左右子树,树的head就是
class BSTreeNode:
    def __init__(self,value=None,left=None,right=None):
        self.value=value
        self.left=left
        self.right=right

def ConnectTreeNodes(pNodeA1, pNodeA2, pNodeA3):
    pNodeA1.left=pNodeA2
    pNodeA1.right=pNodeA3
#
# @param root The root node of the tree
# @return The head node of the converted list.
#
def treeToLinkedList(root):
    def helper(root):
        lt,rh=BSTreeNode(),BSTreeNode()#lt是节点左子树的tail,rh是右子树的head
        #基准情况
        if root is None:
            return (None,None)
        # print (root.left.value,root.right.value)
        (head,lt)=helper(root.left)#节点的head就是左子树的head
        (rh,tail)=helper(root.right)#节点的tail就是右子树的tail
        if lt is not  None:
            lt.right=root
            root.left=lt
        else:
            head=root
        if rh is not None:
            root.right=rh
            rh.left=root
        else:
            tail=root

        return head,tail

    return helper( root);

#另一种写法,更简单
def treeToLinkedList2(root):
    #这一步是因为convertNode返回的是尾部节点
    pTailList=None
    pTailList=convertNode(root,pTailList)
    # print (pTailList.value)
    while pTailList and pTailList.left:
        # print (pTailList.value)
        pTailList=pTailList.left
    return pTailList

def convertNode(root,pTailList):
    #有点像中序遍历
    #对于左子树,lastnode就是左子树的lastnode
    #对于右子树,lastnode上就是根
    #循环不变式:转换到节点P的时候,其左边已经转换成了有序的列表,而且其最后面一个是最大的以后
    #            然后转换右边的节点
    if not root:
        return
    pCurrent=root
    if pCurrent.left:
        pTailList=convertNode(pCurrent.left,pTailList)
    pCurrent.left=pTailList
    if pTailList:
        pTailList.right=pCurrent
    pTailList=pCurrent

    if pCurrent.right:
        pTailList=convertNode(pCurrent.right,pTailList)
    return pTailList

def test1():
    node1=BSTreeNode(4)
    node2=BSTreeNode(8)
    node3=BSTreeNode(12)
    node4=BSTreeNode(16)
    node5=BSTreeNode(6,node1,node2)
    node6=BSTreeNode(14,node3,node4)
    node7=BSTreeNode(10,node5,node6)

    # head=treeToLinkedList(node7)[0]
    # while head.right:
    #     print (head.value,end=' ')
    #     head=head.right

    head1=treeToLinkedList2(node7)
    while head1.right:
        print (head1.value,end=' ')
        head1=head1.right

########################################################################
##           9.腾讯面试题:
#给你10分钟时间,根据上排给出十个数,在其下排填出对应的十个数
#要求下排每个数都是先前上排那十个数在下排出现的次数。
#上排的十个数如下:
#【0,1,2,3,4,5,6,7,8,9】
#举一个例子,
#数值: 0,1,2,3,4,5,6,7,8,9
#分配: 6,2,1,0,0,0,1,0,0,0
#0在下排出现了6次,1在下排出现了2次,
#2在下排出现了1次,3在下排出现了0次...                ##
########################################################################
# 这种思路是一种暴力方法,对第一位设置一个数,然后依次设置并且更新
# 如果发现后面的数字遍历所有可能结果都找不到合适的,那么就要更新前面的数字
# 为了减少遍历次数,稍加分析,maxCount
def findCountList(aList):
    maxCount=[9,2,2,2,2,2,2,0,0,0]#maxCount还可以再优化,不过已经算得很快了
    # maxCount=[9,9,9,9,9,1,1,0,0,0]#如果这个maxcout 没那么好,计算时间就会增加很多
    countList=[0]*len(aList)
    def checkResultIsOk(aList,countList):
        for i in range(len(countList)):
            if countList.count(aList[i])!=countList[i]:
                return False
        # print (i,countList.count(aList[i]),countList[i])
        return True

    def findCountListOfIndex(aList,index,countList):
        if checkResultIsOk(aList,countList):
            return True
        if index>=len(aList):
            return
        for i in range(maxCount[index]+1):
            # print (maxCount[index]+1)
            countList[index]=i
            # print (countList)
            if(findCountListOfIndex(aList,index+1,countList)):
                return True
        return False

    findCountListOfIndex(aList,0,countList)
    return countList


def test9():
    print (findCountList(list(range(10))))




########################################################################
#16.题目:输入一颗二元树,从上往下按层打印树的每个结点,同一层中按照从左往右的顺序打印。
#例如输入
#      8
#   /  /
# 6    10
#  //     //
#5  7   9  11
#输出8   6   10   5   7   9   11。
########################################################################
#广度优先算法的二叉树实现,没什么说的,基础中的基础
def BFS(root):
    queue=[root]
    while queue:
        node=queue.pop(0)
        print (node.value,end=' ')
        if node.left:
            queue.append(node.left)
        if node.right:
            queue.append(node.right)

def DFS(root):
    pass
#就是前序,中序,后序遍历
#二叉树的前序,中序,后序遍历都是深度优先遍历的一种

#            10
#         /      \
#       5        12
#       /\
#      4  7
def Test16():
    pNode10 = BSTreeNode(10);
    pNode5 = BSTreeNode(5)
    pNode12 = BSTreeNode(12)
    pNode4 = BSTreeNode(4)
    pNode7 = BSTreeNode(7)
    ConnectTreeNodes(pNode10, pNode5, pNode12)
    ConnectTreeNodes(pNode5, pNode4, pNode7)

    BFS( pNode10)

########################################################################
#第20 题:
#题目:输入一个表示整数的字符串,把该字符串转换成整数并输出。
#例如输入字符串"345",则输出整数345。
########################################################################
# 不妨查看python的int函数
#int('-12')

########################################################################
#有4张红色的牌和4张蓝色的牌,主持人先拿任意两张,
#再分别在A、B、C三人额头上贴任意两张牌,
##看完后让他们猜自己额头上是什么颜色的牌,
#A说不知道,B说不知道,C说不知道,然后A说知道了。
#请教如何推理,A是怎么知道的。如果用程序,又怎么实现呢?
########################################################################
#A,说自己不知道,那么B,C可能为[(rr,bb),(bb,rr),(rr,rb),(rb,rb),(rb,rr),(rb,bb),(bb,rb)]
#同理B说不知道说明上面的对应关系不能确定B则B=[(rr),(rb),(bb)](所有可能的,没有改进),
# AC=[(rr,bb),(bb,rr),(rr,rb),(rb,rb),(rb,rr),(rb,bb),(bb,rb)]
# AB=[(rr,bb),(bb,rr),(rr,rb),(rb,rb),(rb,rr),(rb,bb),(bb,rb)]
# 这样就得到了所有的AC,AB,对应关系,那么从BC中根据BC的值取出A有且仅有一个值的就是解

import collections
import itertools
def findA():
    possibilities=set(itertools.permutations(['rr','rr','rb','rb','bb','bb'],2))-{('rr','rr'),('bb','bb')}
    #转换成字典更方便
    dictBA=dictCA=collections.defaultdict(set)
    for item in possibilities:
        dictCA[item[1]].add(item[0])
    A=None
    for C in {'rr','bb','rb'}:
        for B in {'rr','bb','rb'}:
            A=dictCA[C]&dictBA[B]
            if len(A)==1:
                print (A,B,C)



if __name__=='__main__':
    findA()
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值