315. 計算右側(cè)小于當(dāng)前元素的個數(shù)

題目

(https://leetcode-cn.com/problems/count-of-smaller-numbers-after-self/)
給定一個整數(shù)數(shù)組 nums,按要求返回一個新數(shù)組 counts。數(shù)組 counts 有該性質(zhì): counts[i] 的值是 nums[i] 右側(cè)小于 nums[i] 的元素的數(shù)量。

示例:

輸入: [5,2,6,1]
輸出: [2,1,1,0]
解釋:
5 的右側(cè)有 2 個更小的元素 (2 和 1).
2 的右側(cè)僅有 1 個更小的元素 (1).
6 的右側(cè)有 1 個更小的元素 (1).
1 的右側(cè)有 0 個更小的元素.
在真實的面試中遇到過這道題?

分析

二話不說使用暴力解題(雙重遍歷)。超時。
嗯,要對代碼進(jìn)行優(yōu)化
這道題從后往前遍歷會比較清楚明了。優(yōu)化點主要在sorted這個數(shù)列。這個sorted實現(xiàn)了對遍歷到當(dāng)前i之后的數(shù)據(jù)進(jìn)行排序插入、然后就可以使用二分法進(jìn)行獲取當(dāng)前大于或者等于nums[i]的第一個位置。這個位置就是當(dāng)前值的逆序數(shù)

代碼

 class Solution {
        public List<Integer> countSmaller(int[] nums) {
            Integer[] res = new Integer[nums.length];
            //sort其實是關(guān)鍵。sort的目的是 對i后面的元素進(jìn)行從小到大的排序。
            // 每次插入新的數(shù)值,前面有幾個數(shù)就是這個數(shù)值現(xiàn)在的逆序數(shù)
            List<Integer> sorted = new ArrayList<>(nums.length);
            int length = nums.length;
            // 從后往前計算
            for (int i = length - 1; i >= 0; i--) {
                int idx = binarySearch(sorted, nums[i]);
                res[i] = idx;
                //實現(xiàn)對sorted的排序。
                sorted.add(idx, nums[i]);
            }

            return Arrays.asList(res);
        }
        // 使用二分法。找大于或等于key的第一個位置
        private int binarySearch(List<Integer> list, int key) {
            int l = 0;
            int r = list.size();
            while(l<r){
                 int m = l + (r - l) / 2;
        if (list.get(m) < key) {
            l = m + 1;
        } else {
                r = m;
        } 
            }
            return l;
        }
    }

結(jié)果

image.png
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容