搜索:顺序,二分,二叉,哈希

二分

二分查找只能用有序顺序表:折半查找

一些小问题:len(nums)=n 是n个数,从一开始,而下标是从0开始 因此最后一个下标为n-1

二分(非递归方式)(递归方式)

set函数去除重复值

sort()排序顺序排序

二分查找非递归:用双指针

例1.二分查找非递归

查找两个数的交级应该是这题dd

class Solution:
    def intersect(self, nums1: List[int], nums2: List[int]) -> List[int]:
        res=[]
        
        nums1.sort()
        nums2.sort()
        i ,j =0,0
        while i<len(nums1)and j<len(nums2):
            if nums1[i]<nums2[j]:
                i +=1
            elif nums1[i]> nums2[j]:
                j+=1
            else:
                res.append(nums1[i])
                i+=1
                j+=1
        return res

class Solution:
    def missingNumber(self, nums: List[int]) -> int:
        nums.sort()
        i = len(nums)
        
        for j in range(len(nums)):
            if j != nums[j]:
                return j
        else:
                i != nums[j]
                return i

        

class Solution:
    def missingNumber(self, nums: List[int]) -> int:
        i = len(nums)
        j = (0+i)*(i+1)//2
        a = j -sum(nums)
        return a


 

class Solution:
    def intersection(self, nums1: List[int], nums2: List[int]) -> List[int]:
        res =[]
        for i in nums1:
            if i in nums2 and i not in res:
                res.append(i)
        return res

class Solution:
    def search(self, nums: List[int], target: int) -> int:
        res=[]
        for i in range(len(nums)):

            if target == nums[i]:
                res.append(i)
                return i
        if target not in nums:
            return -1

            

    

二分查找时间复杂度  2^x=n

O(logn)

二叉树

树:类似表格

定义:每个节点有零个或多个子树

没有父节点的节点称为根节点

每一个非根节点有且只有一个父节点

除了根节点,每个子节点可以分为多个不相交的子树

树的术语

节点的度:一个节点含有的子树个数

树的度:那个节点的度最大,就是树的度

叶子节点或终端节点:没有子节点的

父节点:一个节点含有子节点,那么这个子节点的父节点,就是这个节点

兄弟节点:相同父节点的子节点

节点的层次:从根开始为一,根的子节点为2

树的高度:

树的种类:

  • 无序树
  • 有序树
    • 二叉树:每个节点最多含有两个子树
      • 完全二叉树:除了最下层的度没达到二个节点,其他层都达到了两个节点
      • 满二叉树:所有层都达到了2
      • 平衡二叉树:任何节点两个子树的高度差不大于1
      • 排序二叉树:就是若它的左子树不空,则左子树上所有节点的值均小于它的根节点的值;

树的存储

  • 顺序存储:此存储方式占空间较大
  • 链式存储:

常见的一些树的应用场景

xml,html

路由协议

mysql

二叉树的性质

  1. 在二叉树的i层至多有2^(i-1)
  2. 深度为k的二叉树最多有2^k-1节点

遍历

二叉树的实现

广度遍历

深度遍历

  1. 先序遍历        根左右
  2. 中序遍历        左根右
  3. 后序遍历        左右根

  • 树的构造
  • 递归实现先序遍历、中序遍历、后序遍历
  • 堆栈实现先序遍历、中序遍历、后序遍历
  • 队列实现层次遍历
#coding=utf-8

class Node(object):
    """节点类"""
    def __init__(self, elem=-1, lchild=None, rchild=None):
        self.elem = elem
        self.lchild = lchild
        self.rchild = rchild


class Tree(object):
    """树类"""
    def __init__(self):
        self.root = Node()
        self.myQueue = []

    def add(self, elem):
        """为树添加节点"""
        node = Node(elem)
        if self.root.elem == -1:  # 如果树是空的,则对根节点赋值
            self.root = node
            self.myQueue.append(self.root)
        else:
            treeNode = self.myQueue[0]  # 此结点的子树还没有齐。
            if treeNode.lchild == None:
                treeNode.lchild = node
                self.myQueue.append(treeNode.lchild)
            else:
                treeNode.rchild = node
                self.myQueue.append(treeNode.rchild)
                self.myQueue.pop(0)  # 如果该结点存在右子树,将此结点丢弃。


    def front_digui(self, root):
        """利用递归实现树的先序遍历"""
        if root == None:
            return
        print root.elem,
        self.front_digui(root.lchild)
        self.front_digui(root.rchild)


    def middle_digui(self, root):
        """利用递归实现树的中序遍历"""
        if root == None:
            return
        self.middle_digui(root.lchild)
        print root.elem,
        self.middle_digui(root.rchild)


    def later_digui(self, root):
        """利用递归实现树的后序遍历"""
        if root == None:
            return
        self.later_digui(root.lchild)
        self.later_digui(root.rchild)
        print root.elem,


    def front_stack(self, root):
        """利用堆栈实现树的先序遍历"""
        if root == None:
            return
        myStack = []
        node = root
        while node or myStack:
            while node:                     #从根节点开始,一直找它的左子树
                print node.elem,
                myStack.append(node)
                node = node.lchild
            node = myStack.pop()            #while结束表示当前节点node为空,即前一个节点没有左子树了
            node = node.rchild                  #开始查看它的右子树


    def middle_stack(self, root):
        """利用堆栈实现树的中序遍历"""
        if root == None:
            return
        myStack = []
        node = root
        while node or myStack:
            while node:                     #从根节点开始,一直找它的左子树
                myStack.append(node)
                node = node.lchild
            node = myStack.pop()            #while结束表示当前节点node为空,即前一个节点没有左子树了
            print node.elem,
            node = node.rchild                  #开始查看它的右子树


    def later_stack(self, root):
        """利用堆栈实现树的后序遍历"""
        if root == None:
            return
        myStack1 = []
        myStack2 = []
        node = root
        myStack1.append(node)
        while myStack1:                   #这个while循环的功能是找出后序遍历的逆序,存在myStack2里面
            node = myStack1.pop()
            if node.lchild:
                myStack1.append(node.lchild)
            if node.rchild:
                myStack1.append(node.rchild)
            myStack2.append(node)
        while myStack2:                         #将myStack2中的元素出栈,即为后序遍历次序
            print myStack2.pop().elem,


    def level_queue(self, root):
        """利用队列实现树的层次遍历"""
        if root == None:
            return
        myQueue = []
        node = root
        myQueue.append(node)
        while myQueue:
            node = myQueue.pop(0)
            print node.elem,
            if node.lchild != None:
                myQueue.append(node.lchild)
            if node.rchild != None:
                myQueue.append(node.rchild)


if __name__ == '__main__':
    """主函数"""
    elems = range(10)           #生成十个数据作为树节点
    tree = Tree()          #新建一个树对象
    for elem in elems:                  
        tree.add(elem)           #逐个添加树的节点

    print '队列实现层次遍历:'
    tree.level_queue(tree.root)

    print '\n\n递归实现先序遍历:'
    tree.front_digui(tree.root)
    print '\n递归实现中序遍历:' 
    tree.middle_digui(tree.root)
    print '\n递归实现后序遍历:'
    tree.later_digui(tree.root)

    print '\n\n堆栈实现先序遍历:'
    tree.front_stack(tree.root)
    print '\n堆栈实现中序遍历:'
    tree.middle_stack(tree.root)
    print '\n堆栈实现后序遍历:'
    tree.later_stack(tree.root)
--------------------- 

 例1.

 递归法的

递归
# 时间复杂度:O(n),n为节点数,访问每个节点恰好一次。
# 空间复杂度:空间复杂度:O(h),h为树的高度。最坏情况下需要空间O(n),平均情况为O(logn)

# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution:
    def inorderTraversal(self, root: Optional[TreeNode]) -> List[int]:
        if root == None:
            return []
        
        return self.inorderTraversal(root.left) + [root.val] + self.inorderTraversal(root.right)

 前序遍历

class Solution:
    def preorderTraversal(self, root: Optional[TreeNode]) -> List[int]:
        if root ==None:
            return []
        return ([root.val]+self.preorderTraversal(root.left)+self.preorderTraversal(root.right))

后序遍历

class Solution:

    def postorderTraversal(self, root: Optional[TreeNode]) -> List[int]:
        if root == None:
            return []
        
        return (self.postorderTraversal(root.left)  + self.postorderTraversal(root.right)+[root.val] )

不会的知识

check()函数是当满足查找条件以及向最佳答案压缩的方向返回true,不满足条件返回false

return语句放置在循环体内,循环一共执行了三次,相当于前前后后一共有3个return语句,根据上文对return语句用法介绍——遇到的第一个return即返回(退出def块),所以,当第一个return上传完毕后,直接退出def

if not a:我觉得是判断a是否为空的写法:如果a为空

# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution:
    def isSymmetric(self, root: Optional[TreeNode]) -> bool:
        def recur(L, R):
            if not L and not R: return True   #就是指如果L为空并且R为空,返回True
            if not L or not R or L.val != R.val: return False
            return recur(L.left, R.right) and recur(L.right, R.left)

        return not root or recur(root.left, root.right)

深度优先搜索

广度优先搜索(BFS)。BFS 通常借助 队列 的先入先出特性来实现。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值