算法分析与设计课程02——315. Count of Smaller Numbers After Self (Hard难度)
来源:互联网 发布:python 量化投资 书籍 编辑:程序博客网 时间:2024/05/02 22:34
一、题目描述(中文)
————————————原题链接
任意给一个数组如[5, 2, 6, 1],你需要找出数组中每个数的特征,并返回一个特征数组
特征:这个数后面比这个数小的数 的总和,如第一个数字5,在5后面比5还小的数有2,1**两个数**,所以返回数组第一位是2
所以上面样例数组返回为:[2, 1, 1, 0],见下面具体描述
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.
二、题目分析
以上面样例进行分析[5, 2, 6, 1]
考虑对归并排序归并过程进行处理,归并排序递归树如下:
先定义一个结构封装数组,这个struct有:
1、数组值
2、索引值
3、计数器【用于储存比它小的数,可以用vector实现】
如图,对归并过程进行处理
在5和2归并时,让5成为左边数组L,让2成为右边数组R
进行归并,5>2,所以将2取出,这个时候将左边数组L的每个数的计数器放入1,然后将5取出,得到归并后数组[2, 5],5的计数器里有个2
同样6和1归并,归并后数组[1, 6],6的计数器里有个1
[2, 5] 和 [1, 6] 归并:
①首先取出右边数组R 中的1,将1放入2和5的计数器中
②取出左边数组L的2,不放入任何计数器
③取出左边数组L的5,不放入任何计数器
④取出右边数组R的6,准备放入左边数组L,但L已经没有数了(因为2和5都被取出来了),所以不能放入计数器中
最后归并结果[1, 2, 5, 6],计数器里数值为
1:计数器里没有值
2:1
5:2,1【首先放入2,再放入1】
6:1
根据上面封装的数据结构里的原始索引下标,对于数组[5, 2, 6, 1]
1–>4
2–>2
5–>1
6–>3
结合索引值和计数器里的数值,我们得到最终返回数组[2, 1, 1, 0]
三、源代码【这个代码能够独立运行,如果需要在题目链接下的网站测试,需要做些修改】
实现细节:
1、 封装数据结构不需要默认构造函数是因为,下面使用到的new操作符不会使用这个默认构造函数
2、在数据结构里重载“=”操作符的时候,需要将原来的计数器清空来接收新的计数器值【具体见源码】
#include <iostream>#include <vector>using namespace std;/*定义一个struct封装数组array这个struct有:1、数组值 2、下标索引 3、smaller_numbers的计数器【一个vector数组】 */ struct my_array{ int value; int index; vector<int> smaller_numbers; my_array &operator = (const my_array& b) { value = b.value; index = b.index; int size = b.smaller_numbers.size(); smaller_numbers.clear(); for(int i = 0; i < size; i ++) smaller_numbers.push_back(b.smaller_numbers[i]); return *this; }};vector<int> count_smaller_numbers(my_array* array, int n_size);void merge_sort(my_array* array, int start, int end);void merge(my_array* array, int start, int mid, int end);int main(){ //获取数组 int n_size = 0; cin >> n_size; my_array* array = new my_array[n_size]; for(int i = 0; i < n_size; i ++) { cin >> array[i].value; array[i].index = i; } vector<int> result = count_smaller_numbers(array, n_size); for(int i = 0; i < result.size(); i ++) cout << result[i] << " "; return 0;}vector<int> count_smaller_numbers(my_array* array, int n_size){ merge_sort(array, 0, n_size - 1); //根据struct里的索引值和vector大小创建一个数组存储结果 vector<int> result = vector<int>(n_size, 0);//创建一个大小为 n_size 的 vector 并将其全初始化为 0 for(int i = 0; i < n_size; i ++) result[array[i].index] = array[i].smaller_numbers.size(); return result;}void merge_sort(my_array* array, int start, int end){ if(start < end) { int mid = (start + end) / 2; merge_sort(array, start, mid); merge_sort(array, mid + 1, end); merge(array, start, mid, end); }}void merge(my_array* array, int start, int mid, int end){ /*将左边数组与右边数组归并,原则如下: 只有右边数组归并到结果数组中时,才使剩下的左边数组中的smaller_numbers计数 */ //将其分为左边数组和右边数组,并赋值 int left_size = mid - start + 1; int right_size = end - mid; my_array* left = new my_array[left_size]; my_array* right = new my_array[right_size]; for(int i = 0, k = start; k <= mid; k ++) left[i ++] = array[k]; for(int i = 0, k = mid + 1; k <= end; k ++) right[i ++] = array[k]; //进行归并 int left_count = 0; int right_count = 0; int a_count = start;//记录array数组的起始位置 while(left_count < left_size && right_count < right_size) { if(left[left_count].value > right[right_count].value) { array[a_count ++] = right[right_count]; int select = right[right_count].value; for(int i = left_count; i < left_size; i ++) left[i].smaller_numbers.push_back(select); right_count ++; } else { array[a_count ++] = left[left_count ++]; } } while(left_count < left_size) array[a_count ++] = left[left_count ++]; while(right_count < right_size) array[a_count ++] = right[right_count ++]; delete [] left; delete [] right; }
- 算法分析与设计课程02——315. Count of Smaller Numbers After Self (Hard难度)
- 分治系列——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
- 剑指Offer:从上往下打印二叉树
- addTextChangedListener在fragment中多次执行问题
- 深入理解Volatile,synchronized,原子操作的必要性
- Echart在使用webpack打包之后,IE10+中无法渲染的问题
- 455. Assign Cookies
- 算法分析与设计课程02——315. Count of Smaller Numbers After Self (Hard难度)
- poj 1789 Truck History 最小生成树模板题
- Netty高性能之道1-传统RPC调用性能差的三宗罪
- iOS GPUImage研究序二:更简单GPUImage导入方式
- RabbitMQ~广播消息
- C#调用外部程序
- cmake make
- 2017-03-04 【NOIP2003】神经网络 模拟
- 两个div显示一行时的问题