[Leetcode]42.二叉搜索树中的众数

题目:给定一个有相同值的二叉搜索树(BST),找出 BST 中的所有众数(出现频率最高的元素)。

假定 BST 有如下定义:

  • 结点左子树中所含结点的值小于等于当前结点的值
  • 结点右子树中所含结点的值大于等于当前结点的值
  • 左子树和右子树都是二叉搜索树

例如:
给定 BST [1,null,2,2],

   1
    \
     2
    /
   2

返回[2].

 

思想:遍历这棵二叉搜索树,观察到重复的元素都是相邻的,设置一个计数器用于计数重复最多的元素出现的次数,一个数组用于保存出现最多的元素,如果出现大于当前重复次数的元素,将数组清空放入新的元素。

其中遍历方法可以采用中序遍历递归的方法,也可以使用morris来优化这个过程。

其中morris遍历的主要思想如下:

记当前节点为cur。

  1. 如果cur无左孩子,cur向右移动(cur=cur.right)
  2. 如果cur有左孩子,找到cur左子树上最右的节点,记为mostright
    1. 如果mostright的right指针指向空,让其指向cur,cur向左移动(cur=cur.left)
    2. 如果mostright的right指针指向cur,让其指向空,cur向右移动(cur=cur.right)

实现以上的原则,即实现了morris遍历。

这种方法可以使得遍历的过程不需要额外记录和递归的过程。

递归中序遍历方法:

func findMode(root *TreeNode) []int {
	var res []int
	var repeat int = 0
	var maxrepeat int = 0
	var cur int
	update := func(x int){
		if x == cur{
			repeat++
		}else{
			cur , repeat = x,1
		}
		if repeat == maxrepeat{
			res = append(res,cur)
		}else if repeat> maxrepeat{
            maxrepeat = repeat
			res = []int{cur}
		}
	}

	var dfs func(root *TreeNode)
	dfs = func(root *TreeNode) {
		if root==nil{
			return
		}else{
			dfs(root.Left)
			update(root.Val)
			dfs(root.Right)
		}
	}
	dfs(root)
	return res
}

 morris优化方法:

func findMode(root *TreeNode) []int {
	var res []int
	var repeat int = 0
	var maxrepeat int = 0
	var cur int
	var curnode = root
	update := func(x int){
		if x == cur{
			repeat++
		}else{
			cur , repeat = x,1
		}
		if repeat == maxrepeat{
			res = append(res,cur)
		}else if repeat> maxrepeat{
			res = []int{cur}
		}
	}
	for curnode!=nil{
		if curnode.Left==nil{
			update(curnode.Val)
			curnode = curnode.Right
			continue
		}
		pre := curnode.Left
		for pre.Right!=nil&&pre.Right!=curnode{
			pre = pre.Right
		}
		if pre.Right ==nil{
			pre.Right = curnode
			curnode=curnode.Left
		}else{
			pre.Right = nil
			update(curnode.Val)
			curnode =curnode.Right
		}

	}
	return res
}

 

题目来源:https://leetcode-cn.com/problems/find-mode-in-binary-search-tree/submissions/

posted @ 2021-12-16 15:00  梦想是能睡八小时的猪  阅读(34)  评论(0)    收藏  举报