赞
踩
Leetcode 315
h
a
r
d
\color{#FF0000}{hard}
hard
点击进入原题链接:Leetcode 315 计算右侧小于当前元素的个数 Count of Smaller Numbers After Self
You are given an integer array nums and you have to return a new counts array. The counts array has the property where counts[i] is the number of smaller elements to the right of nums[i].
给定一个整数数组 nums,按要求返回一个新数组 counts。数组 counts 有该性质: counts[i] 的值是 nums[i] 右侧小于 nums[i] 的元素的数量。
j
是后半个数组中第j
个元素,同时也代表了比前半个数组中第i
个元素小的元素个数,由于后半个数组元素在nums
数组里肯定是排在前半个数组的后面的,因此j
就代表着当前的逆序数。j
就可以得到最终每个元素对于整个序列而言的逆序数。nums
数组不一样了,而题目要求的逆序数数组counts
数组是按照nums
数组的顺序的,因此我们需要给每个nums
数组的元素加上一个序号,形成一个pair
,这样在修改counts
数组的时候,根据 pair.second
(也就是该元素在nums
里的原序号)来索引,就不会混乱了。class Solution { public: vector<int> countSmaller(vector<int>& nums) { // 主函数,用于初始化,调用功能函数,返回结果 vector<pair<int,int>> vec; int len = nums.size(); vector<int> counts(len,0); for(int i=0;i<len;i++){ //绑定元素和该元素在原数组nums的位置 vec.push_back(make_pair(nums[i],i)); } merge_sort(vec,counts); return counts; } private: void merge_two_sorted_list(vector<pair<int,int>>& vec,vector<pair<int,int>>& vec1, vector<pair<int,int>>& vec2,vector<int>& counts){ // 最核心的部分,合并两个自序列的同时修改counts数组 int i = 0; // for vec1 int j = 0; // for vec2 int len_vec1 = vec1.size(); int len_vec2 = vec2.size(); while(i<len_vec1 && j<len_vec2){ // 根据每个元素的大小合并vec1\vec2到vec里 if(vec1[i].first <= vec2[j].first){ counts[vec1[i].second] += j; //插前半段元素的时候要注意对counts数组的更新 vec.push_back(vec1[i]); //把元素插入到新的vec函数里 i++; } else{ vec.push_back(vec2[j]); j++; } } //handle the rest of vec1 and vec2(if exist) for(;i<len_vec1;i++){ counts[vec1[i].second] += j; //插前半段元素的时候要注意对counts数组的更新 vec.push_back(vec1[i]); } for(;j<len_vec2;j++){ vec.push_back(vec2[j]); } } void merge_sort(vector<pair<int,int>>& vec,vector<int>& counts){ //递归归并排序函数,用于对原来数组进行二分 int len = vec.size(); if(len<2){ //二分到只有一个元素就return,回溯到上一级 return; } vector<pair<int,int>> vec1; vector<pair<int,int>> vec2; //二分vec到vec1和vec2 int mid = len/2; for(int i=0;i<mid;i++){ vec1.push_back(vec[i]); } for(int i=mid;i<len;i++){ vec2.push_back(vec[i]); } merge_sort(vec1,counts); //继续二分左半个数组 merge_sort(vec2,counts); //继续二分右半个数组 vec.clear(); //清空vec,以便容纳合并后的vec merge_two_sorted_list(vec,vec1,vec2,counts); } };
【小白爬Leetcode315】6.4 (搜索二叉树版)计算右侧小于当前元素的个数 Count of Smaller Numbers After Self
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。