当前位置: 首页 > news >正文

归并|线段树|树状数组

 

 

 

lc315

树状数组应该是最优

暴力的二分..

class Solution {
public:
vector<int> countSmaller(vector<int>& nums) {
vector<int>t,res(nums.size());
/*初始化t,res*/
for(int i=nums.size()-1;i>=0;i--){
int left=0,right=t.size();
/*下面是一个在t数组里二分查找的过程*/
while (left<right){
int mid=left+(right-left)/2;
if(t[mid]>=nums[i]){
right= mid;
}
else{
left=mid+1;
}
}
res[i]=right;
t.insert(t.begin()+right,nums[i]);
}
return res;
}
};

 

归并

class Solution
{
public:
vector<pair<int, int>> a, b;
vector<int> res;
vector<int> countSmaller(vector<int> &nums)
{
int n = nums.size();
for (int i = 0; i < n; ++i)
a.push_back({nums[i], i});
b.resize(n);
res.resize(n);
dfs(0, n - 1);
return res;
}
void dfs(int l, int r)
{
if (l == r)
return;
int mid = (l + r) >> 1;
// 归并是后序遍历的统计模式 所以我们先递归 再合并。
dfs(l, mid);
dfs(mid + 1, r);
for (int i = l; i <= r; ++i)
b[i] = a[i];
int i = l, j = mid + 1, k = l;
while (i <= mid || j <= r)
{
if (i > mid)
a[k++] = b[j++];
else if (j > r)
a[k++] = b[i++];
else if (b[i].first <= b[j].first)
a[k++] = b[j++];//逆序合并
else
{
res[b[i].second] += r - j + 1;
a[k++] = b[i++];
}
}
}
};

 

树状数组

const int MAXN = 100007;

int cnt[MAXN],n;
/*数组cnt[i]用于记录出现元素nums[i]的个数*/
class Solution {
public:
inline void add(int k)
{
for(; k <= n; k += -k&k) cnt[k] += 1;
}

int sum(int k)
{
int res = 0;
for(; k; k -= -k&k) res += cnt[k];
return res;
}

vector<int> countSmaller(vector<int>& nums) {
n = nums.size();
vector<int> ans(n);
vector<pair<int, int>> A;
/*建立一个从数组内容到未排序前索引的映射A*/
for(int i = 0; i < n; i ++) {
A.push_back({nums[i], i+1});
}
memset(cnt, 0, sizeof(cnt));
sort(A.begin(), A.end());
/*进行排序*/
for(int i = 0; i < n; i ++) {
int id = A[i].second;
int t = sum(n) - sum(id);
ans[id-1] = t;
add(id);
}
return ans;
}
};

 

二叉搜索树

struct BSTNode{
int val;
int count;
BSTNode *left;
BSTNode *right;
BSTNode(int x)
: val(x)
, left(NULL)
, right(NULL)
, count(0)
{}
};
/*建立一个二分查找树,每个树结点有四个值,分别是:
int val;这个结点代表的值val
int count;这个val代表的次数也就是在nums数组种比val小的数的个数
left 左子树指针
right 右子树指针
一个构造函数,构造函数如上定义
*/

void BST_insert(BSTNode *node,BSTNode *insert_node,int &count_small)
{
if(node->val >= insert_node->val)
{
/*插入的结点更小,被比较结点(即node)的count++,然后插入到左子树(如果不为空)*/
node->count++;
if(node->left)
{
BST_insert(node->left,insert_node,count_small);
}
else
{
/*左子树为空,插入结点就作为当前结点的左孩子*/
node->left = insert_node;
}
}
else{
/*插入的结点更大,需要在右子树(如果不为空)继续找*/
count_small += node->count + 1;
if(node->right)
{
BST_insert(node->right,insert_node,count_small);
}
else
{
/*当前右子树为空,插入结点作为当前结点右孩子*/
node->right = insert_node;
}
}
}
/*count_small作为一个引用的参数,在递归寻找子树的时候作为一个“类似全局变量”的存在*/


class Solution {
public:
vector<int> countSmaller(vector<int>& nums) {
int n=nums.size();
/*如果数组为空返回空值*/
if(n==0)return {};
vector<int> count;
count.push_back(0);
/*建立一个二叉搜素树*/
BSTNode* node=new BSTNode(nums[n-1]);
int count_small;
for(int i = 1;i < n;i++)
{
count_small = 0;
BST_insert(node,new BSTNode(nums[n-i-1]),count_small);
count.push_back(count_small);
}
/*最后不要忘记删除树节点*/
delete node;
reverse(count.begin(),count.end());
/*push_back的时候是逆序的,此时只要将count数组reverse即可*/
return count;
}
};

 

 

http://www.dtcms.com/a/554153.html

相关文章:

  • 淘宝客网站程序模板便利的广州微网站建设
  • RAGFlow:部署、理论与实战(一)
  • 西安专业网站制作服务专门做动漫的网站有哪些
  • 使用 Python 向 PDF 添加附件与附件注释
  • 【开题答辩全过程】以 基于java的社区疫情防控系统设计与实现 为例,包含答辩的问题和答案
  • Android ble和经典蓝牙
  • 海珠区专业做网站公司wordpress基于谷歌框架
  • 上海网站建设制作跨境电商多平台运营
  • 军队文职资源合集
  • 堆叠和级联的详细描述
  • (125页PPT)IBM流程架构方法论及案例(附下载方式)
  • 基于AS32A601型MCU芯片的屏幕驱动IC方案的技术研究
  • 小米铁蛋电机1代驱动开发
  • 甘肃省网站备案公司网站建设设计公司哪家好
  • html5 网站建设方案中国排名高的购物网站
  • 【更新至 135 个】第一性原理计算 + 数据处理程序
  • frp+公网服务器实现内网穿透方案
  • 变量与可变性:Rust中的数据绑定
  • OpenCV:BGR/RGB转I420(颜色失真),再转NV12
  • 社区网站模板全屋设计装修效果图
  • 404-Spring AI Alibaba Graph 可观测性 Langfuse 功能完整案例
  • 济南住房和城乡建设厅网站小程序制作流程及步骤
  • 测试分类介绍
  • 上海川沙网站建设goood 谷德设计网官网
  • 做网站买什么笔记本好wordpress 关闭自动保存
  • 用jsp做网站登录界面模板代理记账公司哪家好
  • 如何在 Bash 命令中执行命令 (嵌套命令) ?
  • Java调用DeepSeek-R1大模型实现商品订单信息提取
  • postgresql 高频使用语句
  • tiago moveit环境配置过程