leetcode 493 翻转对
z

给定一个数组 nums ,如果 i < j 且 nums[i] > 2*nums[j] 我们就将 (i, j) 称作一个重要翻转对。

你需要返回给定数组中的重要翻转对的数量。

示例 1:

输入: [1,3,2,3,1]
输出: 2
示例 2:

输入: [2,4,3,5,1]
输出: 3
注意:

给定数组的长度不会超过50000。
输入数组中的所有数字都在32位整数的表示范围内。
链接:https://leetcode-cn.com/problems/reverse-pairs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
class Solution(object):
def reversePairs(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
dic = {}
cnt = 0
s = []
for i in nums[::-1]:
if not s:
s.append(i*2)
else:
# 二分搜索
l, r = 0, len(s)-1
while l <= r:
mid = (l + r) >> 1
if s[mid] >= i:
r = mid - 1
else:
l = mid + 1
cnt += l
# 二分插入
l, r = 0, len(s)-1
while l <= r:
mid = (l + r) >> 1
if s[mid] > 2*i:
r = mid - 1
else:
l = mid + 1
s = s[:l] + [2*i] + s[l:]
return cnt
1
2
3
4
5
6
7
8
9
10

import bisect

class Solution:
def reversePairs(self, nums: List[int]) -> int:
ri, res, n = [], 0, len(nums)
for i in reversed(range(0, n)):
res += bisect.bisect_left(ri, nums[i])
bisect.insort(ri, 2 * nums[i])
return res
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
def reversePairs(self, nums: List[int]) -> int:
self.inversions = 0
self.Merge_Sort(nums, 0, len(nums)-1)
return self.inversions

def Merge_Sort(self, nums, l, r):
if l >= r:
return
mid = l + (r - l) // 2
self.Merge_Sort(nums, l, mid)
self.Merge_Sort(nums, mid+1, r)
i, j = l, mid+1
while i <= mid and j <= r:
if nums[j]*2 < nums[i]:
# 当前左半部分,右半部分是排序好的
# 左半部分的当前元素满足,则前元素的右边元素也满足
# 故 mid + 1 - i
self.inversions += mid + 1 - i
j += 1
else:
i += 1
# 排序
nums[l:r+1] = sorted(nums[l:r+1])