LeetCode 315. 计算右侧小于当前元素的个数(二叉查找树二分查找归并排序逆序数总结)

文章目录

    • 1. 题目
    • 2. 解题
      • 2.1 二叉查找树
      • 2.2 二分插入
      • 2.3 归并排序

1. 题目

给定一个整数数组 nums,按要求返回一个新数组 counts。数组 counts 有该性质: counts[i] 的值是 nums[i] 右侧小于 nums[i] 的元素的数量。

示例:
输入: [5,2,6,1]
输出: [2,1,1,0] 
解释:
5 的右侧有 2 个更小的元素 (21).
2 的右侧仅有 1 个更小的元素 (1).
6 的右侧有 1 个更小的元素 (1).
1 的右侧有 0 个更小的元素.

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/count-of-smaller-numbers-after-self
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

2. 解题

2.1 二叉查找树

我的博客 二叉查找树

  • 每个节点增加一个数据count(记录比这个节点小的元素个数)
  • 如果新加入的节点小于当前节点cur,cur->count++
  • 从根节点root向下查找,满足条件则累加count值&&路过的比自己小的元素个数
  • 特别注意,将原数组逆向(从右向左)插入BST(题目要求找的是右边比我小的)
  • 时间复杂度O(nlgn)

在这里插入图片描述
在这里插入图片描述

  • 最坏情况下,BST退化成链表,时间复杂度变成O(n2)
class Node	//树的节点
{
public:int val;int count;//小于该节点的个数Node *left, *right;Node(int v): val(v), count(0), left(NULL), right(NULL){}
};
class BST
{Node *root;
public:BST():root(NULL){}int insert(int n){return insert(n, root);}
private:int insert(int n, Node* &cur)//指针的引用,将节点之间连起来{if(!cur){cur = new Node(n);//创建的新节点cur更新至调用处的参数return 0;//自己等于自己,不用加,返回0}else{if(n > cur->val)//我比当前大,+1,还要 +之前记录的比它小的个数,+它右侧的return 1 + cur->count + insert(n,cur->right);if(n < cur->val){	//我比当前小cur->count++;	//比当前小的记录 +1return insert(n,cur->left);//去左边子树里查找}else// ==,+比当前小的个数,+右侧里面的return cur->count + insert(n,cur->right);}}
};
class Solution {
public:vector<int> countSmaller(vector<int>& nums) {vector<int> ans(nums.size());BST tree;for(int i = nums.size()-1; i >= 0; --i)ans[i] = tree.insert(nums[i]);return ans;}
};

在这里插入图片描述

2.2 二分插入

  • 开辟一个空的数组,用于存放已排序的数据
  • 将原数组,从右向左,二分插入至新数组,记录插入的位置(前面有多少小于我的)
class Solution {
public:vector<int> countSmaller(vector<int>& nums) {if(nums.empty())return {};vector<int> ans, sorted;int pos;vector<int>::iterator it;for(int i = nums.size()-1; i >= 0; --i){pos = binaryInsert(sorted,nums[i]);it = sorted.begin()+pos;sorted.insert(it,nums[i]);//可能导致vector数据搬移ans.push_back(pos);}reverse(ans.begin(),ans.end());return ans;}int binaryInsert(vector<int>& sorted, int num){int left = 0, right = sorted.size()-1, mid;while(left <= right){mid = left+((right-left)>>1);if(sorted[mid] < num)left = mid+1;else if(sorted[mid] >= num)right = mid-1;}return left;//自己在纸上测试下,只能是left}
};
  • 时间复杂度也是O(nlgn)
  • 以下结果时间偏长,可能是在vector中间插入数据导致的数据搬移,消耗了时间
    在这里插入图片描述

2.3 归并排序

参考分治,归并求逆序度

借一张图理解一下
在这里插入图片描述

  • 需要归并求解,但是归并排序过程中,数据下标变动了,需要建立一个下标数组
  • 对下标数组idx进行排序(比较大小的时候用nums数组代入比较)
  • 计算逆序数方法(只能取一种,不要同时用)
  • 1、当前序数组写入时,计算后序中已经出列的个数(它们均小于刚写入的),j-(mid+1),有后续操作(前序没写完时,继续累加)
  • 2、当后序数组写入时,计算前序中还有多少没有出队(它们均大于刚写入的),mid-i+1,无后序操作(因为,前序出队完毕,剩余0,或者,后序写入完毕)
    在这里插入图片描述
    再借两张图总结下
    在这里插入图片描述
    在这里插入图片描述
class Solution {vector<int> ans;//存储结果vector<int> temp;//归并排序临时空间vector<int> idx;//归并排序的对象,排的是---下标,不是数值
public:vector<int> countSmaller(vector<int>& nums) {if(nums.empty())return {};ans.resize(nums.size());temp.resize(nums.size());idx.resize(nums.size());for(int i = 0; i < nums.size(); ++i){idx[i] = i;ans[i] = 0;}mergeSort(nums,0,nums.size()-1);return ans;}void mergeSort(vector<int> &nums, int l, int r){if(l == r)return;int mid = l+((r-l)>>1);mergeSort(nums,l,mid);mergeSort(nums,mid+1,r);merge(nums,l,mid,r);}void merge(vector<int>& nums, int l, int mid, int r){int i = l, j = mid+1, k = l;while(i <= mid && j <= r){if(nums[idx[i]] <= nums[idx[j]]){ans[idx[i]] += j-(mid+1);temp[k++] = idx[i++];}else{temp[k++] = idx[j++];}}while(i <= mid){ans[idx[i]] += j-(mid+1);//or ans[idx[i]] += r-mid;temp[k++] = idx[i++];}while(j <= r){temp[k++] = idx[j++];}for(i = l; i <= r; ++i)idx[i] = temp[i];}
};

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/478293.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Python实现共现语义网络

Python实现共现语义网络&#xff1a;

领域应用 | 金融资管领域知识图谱的构建和应用

转载公众号 | DataFunTalk分享嘉宾&#xff1a;李渔 熵简科技 联合创始人编辑整理&#xff1a;唐汝佳出品平台&#xff1a;DataFunTalk导读&#xff1a;本次分享的主题是金融资管领域知识图谱的构建和应用&#xff0c;主要介绍如何运用大数据、AI这些技术手段&#xff0c;来帮助…

我分析了ACL21论文列表,发现对比学习已经...

文 | 花小花Posy小伙伴们&#xff0c;好久不见呀&#xff0c;小花又回来了&#xff01;最近关注对比学习&#xff0c;所以ACL21的论文列表出来后&#xff0c;小花就搜罗了一波&#xff0c;好奇NLPers们都用对比学习干了什么&#xff1f;都是怎么用的呀&#xff1f;效果怎样呀&a…

2016,你最不应该错过的热门技术文章

本文首发在“美团技术团队”微信公众号&#xff0c;内容已覆盖截止至2017年1月23日最新的技术文章。 1955年3月15日&#xff0c;爱因斯坦给刚去世的密友Michele Besso家人的信中说&#xff1a; “像我们这样信仰物理学的人都知道&#xff0c;过去、现在和未来之间的分别只不过是…

LeetCode 629. K个逆序对数组(DP)

文章目录1. 题目2. 动态规划3. 优化的DP1. 题目 给出两个整数 n 和 k&#xff0c;找出所有包含从 1 到 n 的数字&#xff0c;且恰好拥有 k 个逆序对的不同的数组的个数。 逆序对的定义如下&#xff1a;对于数组的第i个和第 j个元素&#xff0c;如果满i < j且 a[i] > a[…

快速的找出元素是否在list中 python

number [[1,2],[3,2]] num np.array(number) np.argwhere(num2) np.argwhere(num2) array([[0, 1], [1, 1]], dtypeint64) 注意&#xff1a;只能是维度相同的时候&#xff0c;才能用该方法。 om ragged nested sequences (which is a list-or-tuple of lists-or-tuples-or nd…

论文浅尝 | 知识图谱的神经符号推理(上)

笔记整理 | 叶橄强&#xff0c;浙江大学在读硕士&#xff0c;研究方向为知识图谱的表示学习和预训练。知识图谱推理是支撑信息提取、信息检索和推荐等机器学习任务的基础组成部分&#xff0c;并且由于知识图可以看作知识的离散符号表示&#xff0c;自然可以利用符号技术做知识图…

ICML2021 | Self-Tuning: 如何减少对标记数据的需求?

文 | 王希梅&#xff0c;高敬涵&#xff0c;龙明盛&#xff0c;王建民源 | THUML本文介绍ICML2021的中稿论文&#xff1a;Self-Tuning for Data-Efficient Deep Learning&#xff0c;就“如何减少对标记数据的需求”这一重要问题给出了我们的思考。论文标题&#xff1a;Self-Tu…

美团点评Docker容器管理平台

本文是郑坤根据第14期美团点评技术沙龙“你不知道的美团云”演讲内容整理而成&#xff0c;已发表在《程序员》杂志2017年1月刊。 美团点评容器平台简介 本文介绍美团点评的Docker容器集群管理平台&#xff08;以下简称“容器平台”&#xff09;。该平台始于2015年&#xff0c;是…

Python 获取本机或者服务器的 IP 地址

获取计算机名称 hostname socket.gethostname() 获取本机 IP ip socket.gethostbyname(hostname) print(ip) 具体操作 import socket hostname socket.gethostname() ip socket.gethostbyname(hostname) print(ip)通常使用 socket.gethostname() 方法即可获取本机 IP …

LeetCode 754. 到达终点数字(数学推理)

1. 题目 在一根无限长的数轴上&#xff0c;你站在0的位置。终点在target的位置。 每次你可以选择向左或向右移动。第 n 次移动&#xff08;从 1 开始&#xff09;&#xff0c;走 n 步。 返回到达终点需要的最小移动次数。 示例 1: 输入: target 3 输出: 2 解释: 第一次移动…

论文浅尝 | 神经符号推理综述(下)

笔记整理 | 许泽众&#xff0c;浙江大学在读博士3、神经驱动的符号推理相比于之前的两种类型&#xff0c;神经驱动的符号推理的目的是挖掘规则&#xff0c;而神经网络在其中扮演的作用是解决纯符号推理的不确定性&#xff0c;并且能够有效的减少搜索空间。这种类型的方法的基本…

Dockerfile构建python 运行项目运行环境

https://blog.csdn.net/qq_24487005/article/details/123380810 目录 构建思路 DockerFile脚本 环境文件解析 pip.conf sources.list openssl.cnf localtime install.sh startup.sh docker镜像构建 构建思路 1、把容器内需要用到的文件全部复制到容器中 2、设置一个工作目录&am…

没有导师指导,该如何自己选题发CVPR?

| 背景底层计算机视觉技术&#xff0c;如图像增强、图像复原等&#xff0c;一直以来都是一个重要且热门的研究方向。传统的方法多基于稀疏编码、小波变换等技术&#xff0c;近年来&#xff0c;深度学习的兴起为该领域带来了新的发展机遇&#xff0c;同时大幅度提升了方法性能。…

Android硬件加速原理与实现简介

在手机客户端尤其是Android应用的开发过程中&#xff0c;我们经常会接触到“硬件加速”这个词。由于操作系统对底层软硬件封装非常完善&#xff0c;上层软件开发者往往对硬件加速的底层原理了解很少&#xff0c;也不清楚了解底层原理的意义&#xff0c;因此常会有一些误解&…

LeetCode 482. 密钥格式化

1. 题目 给定一个密钥字符串S&#xff0c;只包含字母&#xff0c;数字以及 ‘-’&#xff08;破折号&#xff09;。N 个 ‘-’ 将字符串分成了 N1 组。给定一个数字 K&#xff0c;重新格式化字符串&#xff0c;除了第一个分组以外&#xff0c;每个分组要包含 K 个字符&#xf…

暑期学校 | 东南大学2021年国际暑期学校项目:从感知理解到智能认知 (知识图谱及应用课程)...

国际暑期学校开课啦 项目介绍 从感知理解到智能认知——走近新一代人工智能From perceptual understanding to intelligent cognition-Approaching a new generation of AI本项目是由东南大学计算机科学与工程学院、软件学院、人工智能学院组织&#xff0c;通过开设人工智…

The command ‘/bin/sh -c apt-get install -y vim’ returned a non-zzero code: 100

最近在学习docker时&#xff0c;发现使用ubuntu构建镜像时&#xff0c;如果有apt-get install命令&#xff0c;老是出现以下错误&#xff1a;The command ‘/bin/sh -c apt-get install -y vim’ returned a non-zzero code: 100 查了一下&#xff0c;发现很多人都说是使用ubun…

LeetCode 970. 强整数

文章目录1. 题目2. 解题2.1 暴力法2.2 优化双重循环1. 题目 给定两个正整数 x 和 y&#xff0c;如果某一整数等于 xi yj&#xff0c;其中整数 i > 0 且 j > 0&#xff0c;那么我们认为该整数是一个强整数。 返回值小于或等于 bound 的所有强整数组成的列表。 你可以按…

ACL'21 | 弱标签的垃圾数据,也能变废为宝!

文 | LawsonAbs编 | 小戏是不是感觉 NER 领域效果提升太过困难&#xff1f;最近一篇来自 Amazon 的文章提出使用强弱标签结合的方式来解决 NER 的问题。强弱标签结合其实非常立足实际的数据情况——干净又准确的强标签数据非常稀少&#xff0c;更多的是标注质量存在问题的弱标签…