315.计算右侧小于当前元素的个数
链接:315.计算右侧小于当前元素的个数
难度:Hard
标签:树状数组、线段树、数组、二分查找、分治、有序集合、归并排序
简介:给定一个整数数组 nums,按要求返回一个新数组 counts。数组 counts 有该性质: counts[i] 的值是 nums[i] 右侧小于 nums[i] 的元素的数量。
题解 1 - typescript
- 编辑时间:2020-07-11
- 执行用时:828ms
- 内存消耗:38.8MB
- 编程语言:typescript
- 解法介绍:双重循环。
function countSmaller(nums: number[]): number[] {
  const len = nums.length;
  const res: number[] = [];
  for (let i = 0; i < len; i++) {
    let c = 0;
    const num = nums[i];
    for (let j = i + 1; j < len; j++) {
      if (num > nums[j]) cpp;
    }
    res[i] = c;
  }
  return res;
}
题解 2 - typescript
- 编辑时间:2021-05-14
- 执行用时:368ms
- 内存消耗:64.5MB
- 编程语言:typescript
- 解法介绍:分治,统计两部分中下标排序时计算。
function countSmaller(nums: number[]): number[] {
  const len = nums.length;
  if (len === 0) return [];
  const list = new Array(len).fill(0).map((_, i) => i);
  const ans = new Array(len).fill(0);
  const mergeSort = (left: number, right: number): void => {
    if (left === right) return;
    const mid = (left + right) >> 1;
    mergeSort(left, mid);
    mergeSort(mid + 1, right);
    const temp = list.slice(left, mid + 1);
    let p1 = 0,
      end1 = mid - left,
      p2 = mid + 1,
      i = left;
    while (p1 <= end1) {
      if (p2 > right || nums[temp[p1]] <= nums[list[p2]]) {
        const index = temp[p1++];
        list[i++] = index;
        ans[index] += p2 - mid - 1;
      } else {
        list[i++] = list[p2++];
      }
    }
  };
  mergeSort(0, len - 1);
  return ans;
}