分治系列——315. Count of Smaller Numbers After Self[hard]
来源:互联网 发布:洛天依软件下载 编辑:程序博客网 时间:2024/05/17 18:41
题目
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]
.
Example:
Given nums = [5, 2, 6, 1]To the right of 5 there are 2 smaller elements (2 and 1).To the right of 2 there is only 1 smaller element (1).To the right of 6 there is 1 smaller element (1).To the right of 1 there is 0 smaller element.
Return the array [2, 1, 1, 0]
.
解法一(超时)
遍历穷举,全部比较一遍(然而是 HARD,写的时候我就猜到会超时了)
/*class Solution {public: vector<int> countSmaller(vector<int>& nums) { vector<int> result(nums.size(), 0);for (int i = 0; i < nums.size(); i++) {for (int j = i + 1; j < nums.size(); j++) {if (nums[i] > nums[j])result[i]++;}}return result; }};*/
解法二
后来,看讨论区,说是利用归并排序,比较交换次数得到结果。可是,归并两个有序数组时,每个数字下标是在改变的,怎么样去记录交换次数呢?后来翻到了这篇博客,https://siukwan.sinaapp.com/?p=1049 ——博主创建了一个结构保存 value,index和交换次数,受到启发之后开始编写,同时,编写归并排序的借鉴于博客 http://blog.csdn.net/morewindows/article/details/6678165
当然我只是借鉴他们的思想,代码里还有我的一些思考,现在贴出代码并进行解释:
class Solution {public://(1) struct Combine{int value;int index;int right;Combine(int v, int i, int r) {value = v;index = i;right = r;}bool operator <= (Combine& t) {return (this->value <= t.value);}};//(2)void twoArray(vector<Combine>&a, int first1, int first2, int last,vector<Combine> b) {int i = first1;int j = first2+1;//int k = b.size();//vector<int> result(a.size() , 0);while (i <= first2 && j <= last) {if (a[i] <= a[j])b.push_back( a[i++]);else { //(4)for(int h = i; h <= first2;h++)a[h].right++;b.push_back(a[j++]);}}while (i <= first2)b.push_back(a[i++]);while (j <= last)b.push_back(a[j++]);for (int o = 0; o < b.size(); o++) {a[first1+o] = b[o];}b.clear();//b = result;}//(3)void sort22(vector<Combine>& a, int first, int last, vector<Combine> b) {if (first < last) {int mid = (first + last) / 2;sort22(a, first, mid,b);sort22(a, mid+1, last,b); twoArray(a, first, mid,last,b);}}/*设计一个数据结构,这个数据结构记录了原始数组的val,原始数组的idx,以及所求值cnt,然后对这个新的数据结构数组进行mergeSort,同时进行统计。*/vector<int> countSmaller(vector<int>& nums) {vector<Combine> tmp,b;for (int i = 0; i < nums.size(); i++) {tmp.push_back(Combine(nums[i], i, 0));}sort22(tmp, 0, tmp.size() - 1, b);vector<int> hhh(nums.size(), 0);for (int i = 0; i < nums.size(); i++) {hhh[tmp[i].index] = tmp[i].right;}return hhh;}};
解释
首先简单解释 归并排序:
归并排序由两个函数构成,一个是,twoArray, 一个是sort22。 前一个用来把两个有序数组合并成一个,后一个把两个数组变成有序数组(当数组只剩下 1 个元素的时候就是有序的了),两个函数传入的index:first、mid、last要十分注意(我调试了好久才弄明白)。twoArray用了一个临时数组b,因为全部是vector,简化了不少操作。
注释(1)
一个结构,存储了value,原数组的值,index,该值在原数组的下标,以及 right 归并中的交换次数,也就是右侧小于它的数。
注释(2)、注释(3) 看归并排序的介绍
注释(4)
本来以为只是简单的计数交换次数,然而并不是。考虑 5 2 6 1,第一次归并之后:2 5 1 6,接下来,2 1 发生交换,但是 5 里的 right 应该也要增加一,于是我在归并的时候加入
//(4)for(int h = i; h <= first2;h++)a[h].right++;
整道题,主要是体会归并排序,完全是在我写出归并的基础上改的,而且归并巨难写……
- 分治系列——315. Count of Smaller Numbers After Self[hard]
- Hard-题目11:315. Count of Smaller Numbers After Self
- Leetcode 315. Count of Smaller Numbers After Self[hard]
- 315. Count of Smaller Numbers After Self Hard
- leetcode 315. Count of Smaller Numbers After Self(Hard)
- 315. Count of Smaller Numbers After Self
- 315. Count of Smaller Numbers After Self
- 315. Count of Smaller Numbers After Self
- 315. Count of Smaller Numbers After Self
- 315. Count of Smaller Numbers After Self
- 315. Count of Smaller Numbers After Self
- 315. Count of Smaller Numbers After Self***
- 315. Count of Smaller Numbers After Self
- 315. Count of Smaller Numbers After Self
- 315. Count of Smaller Numbers After Self
- 315. Count of Smaller Numbers After Self
- 315. Count of Smaller Numbers After Self
- 315. Count of Smaller Numbers After Self
- call()和applay()方法的区别与详解
- linux APACHE
- 接入七牛上传
- WebStorm-11.0卸载
- Linux 下安装python软件包(pip、nose、virtualenv、distribute )
- 分治系列——315. Count of Smaller Numbers After Self[hard]
- CentOS6.5 Linux安装mysql5.6数据库 针对64位系统
- 考研路上-漫漫考研路(记在清明节)
- MQTT协议、mosquitto安装体验
- Java中直接赋值和new有何不同?
- BZOJ 2594 [Wc2006]水管局长数据加强版
- 基础练习——01子串
- 模拟退火算法——概率法解全局优化
- B. The Meeting Place Cannot Be Changed