493. Reverse Pairs
Posted elaron
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了493. Reverse Pairs相关的知识,希望对你有一定的参考价值。
Given an array nums
, we call (i, j)
an important reverse pair if i < j
and nums[i] > 2*nums[j]
.
You need to return the number of important reverse pairs in the given array.
Example1:
Input: [1,3,2,3,1] Output: 2
Example2:
Input: [2,4,3,5,1] Output: 3
Note:
- The length of the given array will not exceed
50,000
. - All the numbers in the input array are in the range of 32-bit integer.
拿到题目后,最直观的解法就是遍历尝试所有的(i, j)组合,看看有多少种组合满足 i < j
and nums[i] > 2*nums[j]这一条件。
那么,写成代码就是一个嵌套的for循环:
for i:= 0; i < len(nums); i++ { for j := i; j < len(nums); j++ { } }
可以想见,这样解法的时间复杂度为O(n²),空间复杂度为O(1)。
那么,有么有什么办法,可以把时间复杂度降低一些呢?
O(n*n)中,至少有个一个n是无法优化的,因为至少需要遍历每个元素一次,那么第二个n能否降低为<n的值呢?
想象一下,当我们从第0个元素往右遍历的时候,随着index的增加,我们能知道哪些信息?(想象一个卷轴打开的样子,未打开的部分是未知的,已打开的部分就能看的内容)
对于这类顺序展开的情况,我们可以将其抽象成 f(i,j) = f(i, j-1) + c的情况。其中,可以假定f(i, j-1) 已知,我们通过解决c来完成f(i, j)的求解。
那么,在这道题目中,f(i, j-1)是什么,它给我们提供了哪些信息量呢?知道f(i, j-1)后,我们需要做什么才能得到f(i, j)呢?
我们假设 f(i, j) 代表start为i,end为j的范围内,满足nums[i] > 2*nums[j] 这一条件的pair数。
那么,当知道了 f(i, j-1) 后,我们怎么才能得到 f(i, j) 呢?
f(i, j) 相较于 f(i, j-1) 相当于end的index向后移动了一位。我们需要知道从 i 到 j-1 范围内,一共有多少个点满足 nums[i] > 2*nums[j] ,我们想求的是个count计数。
以题目的第二个例子举例:
[2,4,3,5,1]
当访问到第四个元素时(下标为3):
2 | 4 | 3 | 5 |
我们想要知道在第四个元素前面有没有谁是它的2倍以上,并且如果有的话,共有多少个这样的数?
最简单的方法,就是数一下,从[0,j-1]遍历看看有多少个num大于nums[3]*2,写成伪代码为:
result := 0 for j := 0; j < len(nums); j++ { count := 0 for i := 0; i < j; i++ { if nums[i] > 2*nums[j] { count += 1 } } result += count }
但如果这样找的话,每次都需要从头遍历到j位,因此时间复杂度并没有下降,还是O(n²)。那么,有没有什么办法能让我们知道第j位之前,有多少个元素大于2*nums[j]吗?
假如我们把前面 [0, j-1] 个元素排一下序,然后再找找 j-1 位之前,是否出现过大于
Reference:
以上是关于493. Reverse Pairs的主要内容,如果未能解决你的问题,请参考以下文章