• 315. Count of Smaller Numbers After Self


    问题:

    给定一个数组,从左向右遍历数组每一个元素,

    对每一个元素,记录,其右边比他小的元素个数到res数组中。

    求res数组。

    Example:
    Input: [5,2,6,1]
    Output: [2,1,1,0] 
    Explanation:
    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.
    

      

    类似:493. Reverse Pairs

    解法:

    解法一:FenwickTree

    使用以下辅助变量:

    • sortedNums:ftree,对给定数组,进行排序。
    • FenwickTree:sortnums,记录到目前为止,某个排序位置X以前,共有多少元素。(即<=X的元素有多少个)

    由于本题,要求的是某元素以右的更小元素个数。

    我们从后往前进行遍历,即可利用已经记录的结果。

    最后将得到的res进行反转reverse即可。

    代码参考:

     1 class FenwickTree {
     2 public:
     3     FenwickTree(int n):tree(n+1,0) {}
     4     void update(int i, int delta) {
     5         while(i<tree.size()){
     6             tree[i]+=delta;
     7             i+=lowbit(i);
     8         }
     9     }
    10     int preSum(int i){
    11         int sum=0;
    12         while(i>0){
    13             sum+=tree[i];
    14             i-=lowbit(i);
    15         }
    16         return sum;
    17     }
    18 private:
    19     vector<int> tree;
    20     int lowbit(int x) {
    21         return x&(-x);
    22     }
    23 };
    24 class Solution {
    25 public:
    26     vector<int> countSmaller(vector<int>& nums) {
    27         vector<int> res;
    28         FenwickTree ftree(nums.size());
    29         vector<int> sortnums(nums);
    30         sort(sortnums.begin(), sortnums.end());
    31         for(int i=nums.size()-1; i>=0; i--){
    32             int pos = distance(sortnums.begin(), lower_bound(sortnums.begin(), sortnums.end(), nums[i]));
    33             res.push_back(ftree.preSum(pos));
    34             ftree.update(pos+1, 1);
    35         }
    36         reverse(res.begin(), res.end());
    37         return res;
    38     }
    39 };

    解法二:mergeSort

    ⚠️ 注意:由于mergeSort会打乱原来数组的顺序,在mergeSort过程中,要同时保存计数结果,

    需要同时将原来的index位置,存入,使得在mergeSort的过程中,也能找到原来的位置,进行计数。

    • vector<vector<int>> numspos(nums.size(), vector<int>(2,0));
     1 class Solution {
     2 public:
     3     vector<int> countSmaller(vector<int>& nums) {
     4         vector<int> res(nums.size(), 0);
     5         vector<vector<int>> numspos(nums.size(), vector<int>(2,0));
     6         for(int i=0; i<nums.size(); i++){
     7             numspos[i][0]=nums[i];
     8             numspos[i][1]=i;
     9         }
    10         mergeSort(numspos, res, 0, nums.size()-1);
    11         return res;
    12     }
    13     void mergeSort(vector<vector<int>>& nums, vector<int>& res, int start, int end) {
    14         if(end<=start) return;
    15         int mid = start + (end - start) / 2;
    16         mergeSort(nums, res, start, mid);
    17         mergeSort(nums, res, mid+1, end);
    18         merge(nums, res, start, mid, end);
    19     }
    20     void merge(vector<vector<int>>& nums, vector<int>& res, int start, int mid, int end) {
    21         int p=start, q=mid+1, t=0;
    22         vector<vector<int>> tmp(end-start+1, vector<int>(2,0));
    23         for(p=start; p<=mid; p++){
    24             while(q<=end && nums[p][0]>nums[q][0]){
    25                 q++;
    26             }
    27             res[nums[p][1]]+=(q-1-mid);
    28         }
    29         p=start, q=mid+1;
    30         while(p<=mid && q<=end){
    31             if(nums[p][0]>nums[q][0]){
    32                 tmp[t++]=nums[q++];
    33             } else {
    34                 tmp[t++]=nums[p++];
    35             }
    36         }
    37         while(p<=mid){
    38             tmp[t++]=nums[p++];
    39         }
    40         while(q<=end){
    41             tmp[t++]=nums[q++];
    42         }
    43         copy(tmp.begin(), tmp.end(), nums.begin()+start);
    44     }
    45 };
  • 相关阅读:
    列表、元组、字典练习
    周总结04
    站立会议07
    人月神话阅读笔记01
    站立会议06
    站立会议05
    站立会议04
    典型用户需求分析第一期
    站立会议03
    站立会议02
  • 原文地址:https://www.cnblogs.com/habibah-chang/p/13427521.html
Copyright © 2020-2023  润新知