LeetCode题目:315. Count of Smaller Numbers After Self

题目地址:点击打开链接  

题目描述:You are given an integer array nums and you have to return a newcounts array. The counts array has the property where counts[i] is the number of smaller elements to the right ofnums[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].

一开始直接就用暴力比较,但超时了。代码如下:

class Solution {
public:
    vector<int> countSmaller(vector<int>& nums) {
        int l=nums.size();
        if(l==0)return nums;
        vector<int> c;
        int num=0;
        for(int i=0;i<l-1;i++){
            for(int j=i+1;j<l;j++){
                if(nums[i]>nums[j])num++;
            }
            c.push_back(num);
            num=0;
        }
        c.push_back(0);
        return c;
    }
}; 

在论坛中发现一个简单的代码,虽然accept了但是很多人认为O(n^2)的复杂度并不好:
  
0
class Solution {
public:
    vector<int> countSmaller(vector<int>& nums) {
        vector<int> db;
        vector<int> result(nums.size());
        for(int i = nums.size()-1; i >= 0; i--)
        {
            auto it = lower_bound(db.begin(), db.end(), nums[i]);
            result[i] = it - db.begin();
            db.insert(it, nums[i]);
        }
        return result;
    }
};

 

正确的代码如下:

class Solution {
protected:
    void merge_countSmaller(vector<int>& indices, int first, int last, vector<int>& results, vector<int>& nums) {
        int count = last - first;
        if (count > 1) {
            int step = count / 2;
            int mid = first + step;
            merge_countSmaller(indices, first, mid, results, nums);
            merge_countSmaller(indices, mid, last, results, nums);
            vector<int> tmp;
            tmp.reserve(count);
            int idx1 = first;
            int idx2 = mid;
            int semicount = 0;
            while ((idx1 < mid) || (idx2 < last)) {
                if ((idx2 == last) || ((idx1 < mid) &&
                       (nums[indices[idx1]] <= nums[indices[idx2]]))) {
tmp.push_back(indices[idx1]);
                    results[indices[idx1]] += semicount;
                    ++idx1;
                } else {
tmp.push_back(indices[idx2]);
                    ++semicount;
                    ++idx2;
                }
            }
            move(tmp.begin(), tmp.end(), indices.begin()+first);
        }
    }
public:
    vector<int> countSmaller(vector<int>& nums) {
        int n = nums.size();
        vector<int> results(n, 0);
        vector<int> indices(n, 0);
        iota(indices.begin(), indices.end(), 0);
        merge_countSmaller(indices, 0, n, results, nums);
        return results;
    }
};

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值