Leetcode每日一题 计算右侧小于当前元素(golang)

题目

在这里插入图片描述

暴力排序

根据题意,直接用排序的方法可以轻松解决
思路
1.进行两次循环,查找出右侧小于当前元素的个数
代码

func countSmaller(nums []int) []int {
    counts:=[]int{}  //创建空数组counts
  for i, num := range nums{
    count :=0      //先循环遍历num数组,定义一个计数变量count为0
    for j := i + 1; j < len(nums); j++{
      if nums[j] < num {
        count++      //进行内循环,找出右侧小于当前元素的个数
      }
    }
      counts = append(counts,count)  //将count计数合并到count数组中
  }
  return counts
}

在这里插入图片描述
在这里插入图片描述
但是这个方法时间复杂度过高,需要优化
在这里插入图片描述

离散化树状数组

可以看一下官方解题 非常详细

官方解答

二叉搜索树

思路
1.从最右边一个数开始构建二叉搜索树,建树过程中将左子树节点数量计算出来,保存节点数和右边比它小的数的数量
2.如果新插入一个数,更新左子树节点数,如果经过一个节点,并且插入的数比节点的数小,那么就在左子树中继续寻找插入位置,且节点数量加 1
3.如果插入的数比节点的数大,那么就在右子树中寻找

type TreeNode struct {
	Val   int
	leftcount int // 左子树的个数
	Left  *TreeNode
	Right *TreeNode
}

func BST_insert(node *TreeNode, insert_node *TreeNode, small_count *int) {
	if insert_node.Val <= node.Val {    //插入数小于节点数,则继续寻找插入位置,节点数量+1
		node.leftcount++
		if node.Left != nil {
			BST_insert(node.Left, insert_node, small_count)
		} else {
			node.Left = insert_node
		}
	}
	if insert_node.Val > node.Val {
		*small_count = *small_count + node.leftcount + 1  //在右子树查找,计算小于当前元素的个数
		if node.Right != nil {
			BST_insert(node.Right, insert_node, small_count)
		} else {
			node.Right = insert_node
		}
	}
}

func countSmaller(nums []int) []int {
	length := len(nums)
	counts := make([]int, length)
	if length <= 1 {
		return counts     //判断nums数组是否为空
	}
	node := TreeNode{Val: nums[length-1]}
	counts[length-1] = 0
    for i := length - 2; i >= 0; i-- {   //从右到左进行遍历
		var data int
		BST_insert(&node, &TreeNode{Val: nums[i]}, &data)
		counts[i] = data
	}
	return counts
}

时间复杂度大大降低
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_46595591/article/details/107282318