列表

详情


315. 计算右侧小于当前元素的个数

给你一个整数数组 nums ,按要求返回一个新数组 counts 。数组 counts 有该性质: counts[i] 的值是  nums[i] 右侧小于 nums[i] 的元素的数量。

 

示例 1:

输入:nums = [5,2,6,1]
输出:[2,1,1,0] 
解释:
5 的右侧有 2 个更小的元素 (2 和 1)
2 的右侧仅有 1 个更小的元素 (1)
6 的右侧有 1 个更小的元素 (1)
1 的右侧有 0 个更小的元素

示例 2:

输入:nums = [-1]
输出:[0]

示例 3:

输入:nums = [-1,-1]
输出:[0,0]

 

提示:

相似题目

区间和的个数

根据身高重建队列

翻转对

原站题解

去查看

上次编辑到这里,代码来自缓存 点击恢复默认模板
class Solution { public: vector<int> countSmaller(vector<int>& nums) { } };

java 解法, 执行用时: 51 ms, 内存消耗: 61.7 MB, 提交时间: 2022-08-31 10:12:19

class Solution {
  private int[] index;
  private int[] helper;
  private int[] count;

  public List<Integer> countSmaller(int[] nums) {
    List<Integer> res = new ArrayList<>(nums.length);

    index = new int[nums.length];
    helper = new int[nums.length];
    count = new int[nums.length];
    for (int i = 0; i < index.length; i++) {
      index[i] = i;
    }

    merge(nums, 0, nums.length - 1);

    for (int i = 0; i < count.length; i++) {
      res.add(i, count[i]);
    }
    return res;
  }

  private void merge(int[] nums, int s, int e) {
    if (s == e || s > e) return;
    int mid = (s + e) >> 1;

    if (s < mid) {
      merge(nums, s, mid);
    }

    if (mid + 1 < e) {
      merge(nums, mid + 1, e);
    }

    int i = s, j = mid + 1;
    int hi = s;
    while (i <= mid && j <= e) {
      if (nums[index[i]] <= nums[index[j]]) {
        // 右侧出
        helper[hi++] = index[j++];
      } else {
        // 左侧出 计数
        count[index[i]] += e - j + 1;
        helper[hi++] = index[i++];
      }
    }

    while (i <= mid) {
      //左侧出
      helper[hi++] = index[i++];
    }

    while (j <= e) {
      // 右侧出
      helper[hi++] = index[j++];
    }

    for (int k = s; k <= e; k++) {
      index[k] = helper[k];
    }
  }
}

golang 解法, 执行用时: 216 ms, 内存消耗: 11.7 MB, 提交时间: 2022-08-31 10:11:04

// 离散化树状数组
var a, c []int

func countSmaller(nums []int) []int {
    resultList := []int{}
    discretization(nums)
    c = make([]int, len(nums) + 5)
    for i := len(nums) - 1; i >= 0; i-- {
        id := getId(nums[i])
        resultList = append(resultList, query(id - 1))
        update(id)
    }
    for i := 0; i < len(resultList)/2; i++ {
        resultList[i], resultList[len(resultList)-1-i] = resultList[len(resultList)-1-i], resultList[i]
    }
    return resultList
}

func lowBit(x int) int {
    return x & (-x)
}

func update(pos int) {
    for pos < len(c) {
        c[pos]++
        pos += lowBit(pos)
    }
}

func query(pos int) int {
    ret := 0
    for pos > 0 {
        ret += c[pos]
        pos -= lowBit(pos)
    }
    return ret
}

func discretization(nums []int) {
    set := map[int]struct{}{}
    for _, num := range nums {
        set[num] = struct{}{} 
    }
    a = make([]int, 0, len(nums))
    for num := range set {
        a = append(a, num)
    }
    sort.Ints(a)
}

func getId(x int) int {
    return sort.SearchInts(a, x) + 1
}

上一题