美文网首页
剑指offer--algorithm11

剑指offer--algorithm11

作者: strive鱼 | 来源:发表于2018-05-18 15:33 被阅读0次

    菜根谭--摘录续

    量宽福厚 器小禄薄

    仁人心地宽舒,便福厚而庆长,事事成个宽舒气象;鄙夫念头迫促,便禄薄而泽短,事事得个迫促规模。

    情急招损 严厉生恨

    事有急之不白者,宽之或自明,毋躁急以速其忿;人有操之不从者,纵之或自化,毋躁切以益其顽。

    有些事情在很短的时间内想弄明白很困难,可是宽限一些时间 也许就明白了,所以遇事不要急躁,以免增加紧张的气氛;有 些人不容易引导,如果放松对他的约束,也许他会被感化,所以不 要急切地4约籴别人,以免增加对方的抵触情绪。
    切忌浮躁!
    切忌浮躁!
    切忌浮躁!

    性躁无成 平和集福

    性躁心粗者一事无成,心和气平者百福自集。

    题22--二叉树中和为某一值的路径

    输入一颗二叉树和一个整数,打印出二叉树中结点值的和为输入整数的所有路径。
    路径定义为从树的根结点开始往下一直到叶结点所经过的结点形成一条路径。
    

    本题的思路如下


    image.png
    image.png
    image.png

    下面为代码和注释部分

    class tree(object):
        def __init__(self,value):
            self.value=value 
            self.left=None 
            self.right=None 
            
            
    class solution(object):
         def path_to_num(self,root,num):#两个参数,第一个为根节点,第二个为给出的数字
             if not root:
                 return []#边界情况1
             if root.left==None and root.right==None:
                 if num==root.value:
                     return [[root.value]]
                 else:
                     return []#第二种边缘情况
             stack=[]#用于存放路径
             left=self.circle_path(root.left,num-root.value)#先从左边节点开始
             for i in left:#去掉一层,变为单层列表
                 i.insert(0,root.value)#在0的索引位置上插入一个根节点
                 stack.append(i)#然后把整个路径再放回到stack 里
             right=self.circle_path(root.right,num-root.value)#再从右边节点开始
             for j in right:
                 j.insert(0,root.value)
                 stack.append(j)
             return stack       
         def circle_path(self,root,num):#本质上该函数的root
             if not root:
                 return []#依旧是边界情况
             if root.left==None and root.right==None:#说明到了叶节点,也是一种边界情况
                 if num==root.value:
                     return [[root.value]]
                 else:
                     return []
             a=self.circle_path(root.left,num-root.value)+self.circle_path(root.right,num-root.value)#circle_path 方法本质上返回的就是一个双层的列表,因此可以合并
             """
             本题的路径是单向性的贯穿到底,不会即含有左节点,又含有右节点
             这也是为什么会有返回空列表的设定
             """
             return [[root.value]+i for i in a]
            
            
             
        
    
    def main():
        node1=tree(10)
        node2=tree(5)
        node3=tree(12)
        node4=tree(4)
        node5=tree(7)
        
        node1.left=node2
        node1.right=node3
        node2.left=node4
        node2.right=node5
        s=solution()
        print (s.path_to_num(node1,22))
        
        
    if __name__=='__main__':
        main()
    

    本题的关键就在于递归的使用和理解,需要好好的掌握递归的使用

    题23--复杂链表的复制

    输入一个复杂链表(每个节点中有节点值,以及两个指针,
    一个指向下一个节点,另一个特殊指针指向任意一个节点),返回结果为复制后复杂链表的head。
    

    本题涉及到一个节点的两个指针,一个为p_next,一个为p_silbling指针,解决该题,最优的程序设计思路,就是要考虑到时间的复杂度,书中关于一般思路和优化思路的时间复杂度有如下的描述


    image.png
    image.png
    image.png
    image.png

    最后一步就是将一个由原链表和复制的链表组成的链表,拆分为两个链表


    image.png

    下面为程序代码和注释部分,本题还是比较复杂的,需要慢慢体会和理解

    class complex_node(object):
        def __init__(self,value):
            self.value=value
            self.next=None
            self.random=None#随意指针
    
    
    class solution(object):
        def renode(self,node):
            if node==None:
                return None
            self.dup(node)
            self.random_next(node)#此时得到的链表已经是新旧连接的链表了
            self.denode(node) #通过上述的三步实现调用
            
            
        def dup(self,node):#该函数的用途是将原来链表的next指针结构进行复制,并且串联,效果为1--1'--3--3'--5--5'
            pnode=node#实例化一下
            while pnode:#开始循环
                pcloned=complex_node(0)#里面的数字为多少不重要,这一步的意义就是实例化声明一个节点
                pcloned.value=node.value
                pcloned.next=node.next#通过上述的两步进行了复制
                pnode.next=pcloned#实现新旧的连接,实际就是1--1'
                pnode=pcloned.next #进行重新的赋值,开始下一轮的循环
                
                
                
        def random_next(self,node):#该函数的目的实现random节点的连接
            pnode=node#实例化
            while pnode:
                pclone=pnode.next#先进行复制节点的声明
                if pnode.random!=None:
                    pclone.random=pnode.random.next#作用就是将1'和5'连接起来了
                pnode=pclone.next#以便于进行第二次的循环
            
        def denode(self,node):#将新旧的两个链表进行拆分
            pnode=node#还是进行一个实例化的声明
            p1=p2=pnode.next#声明p1,p2的作用就起到拆分新旧链表的桥梁作用
            pnode.next=p1.next#此时1--3
            pnode=pnode.next
            
            while pnode:#此时pnode为3节点
                p2.next=pnode.next#此时1'--3'
                p2=p2.next#进行推移,此时p2为3'
                pnode.next=p2.next#此时3--5
                pnode=pnode.next#进行下一次循环
            return p2
            
            
                
                
                
            
            
            
            
    
    def main():
        node1=complex_node(1)
        node2=complex_node(3)
        node3=complex_node(5)
        node1.next=node2
        node2.next=node3
        node1.random=node3
        s=solution()
        clonenode=s.dup(node1)
        print (clonenode.random.value)
        
        
        
    
    if __name__=='__main__':
        main()
    

    心如止水 方能气贯长虹

    相关文章

      网友评论

          本文标题:剑指offer--algorithm11

          本文链接:https://www.haomeiwen.com/subject/yhapdftx.html