[LeetCode] Reverse Pairs 翻转对
Reverse Pairs 翻转对
题意
计算数组里面下标i小于j,但是i的值要大于j的值的两倍的搭配的个数(也就是可能会有多种搭配);网址
做法
这道题显然是不允许使用最简单的方法:两次循环,逐次进行判断,这样做的时间复杂度就是O(n^2),OJ无法通过,需要考虑另外的实现方式;
class Solution(object):
def reversePairs(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
if not nums:
return 0
count = 0
for i in range(len(nums)):
for j in range(i+1, len(nums)):
if nums[i] > 2 * nums[j]:
count += 1
return count
分治法
利用分治法,将这个问题分成多个问题,每个小问题求出解后,再求出大问题的解,类似归并排序的做法。
可以设想一个数组分成两边的数组,而且两个数组还是有序的,分别记录两个下标i和j,因为i必然小于j,如果当前i的值已经大于当前j的值的*2,那么当前的i和j之前的值显然也必然满足情况,所以直接计算j从中间的位置移动的距离,这就是当前i求出来的个数,然后移动i,只要满足条件的i,就计算他们的求出来的个数,最后都累加起来,就是最终的结果。
class Solution(object):
res = 0
def reversePairs(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
if not nums:
return 0
self.merge_sort(nums, 0, len(nums)-1)
return self.res
def merge_sort(self, nums, left, right):
if right <= left:
return
mid = (left + right) // 2
self.merge_sort(nums, left, mid)
self.merge_sort(nums, mid+1, right)
# 统计个数
count = 0
i, j = left, mid+1
while i <= mid:
if j > right or nums[i] <= 2 * nums[j]:
i += 1
self.res += count
else:
j += 1
count += 1
nums[left:right + 1] = sorted(nums[left:right+1])
或者:
class Solution(object):
def reversePairs(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
if not nums:
return 0
return self.merge_sort(nums, 0, len(nums) - 1)
def merge_sort(self, nums, left, right):
if left >= right:
return 0
mid = (left + right) // 2
res = self.merge_sort(nums, left, mid) + self.merge_sort(nums, mid+1, right)
i, j = left, mid+1
while i <= mid:
while j <= right and nums[i] > nums[j] * 2:
j += 1
res += j - (mid + 1)
i += 1
nums[left:right + 1] = sorted(nums[left:right + 1])
return res
树状数组
树状数组的原理可以参考我的这篇博客,使用树状数组是因为其能够保证较少的时间复杂度来计算前面存在多少个符合规定的数字。
class FenwickTree(object):
def __init__(self, n):
self.n = n
self.sums = [0] * (n + 1)
def low_bit(self, x):
return x & -x
def add(self, x, val):
while x <= self.n:
self.sums[x] += val
x += self.low_bit(x)
def get_sum(self, x):
result = 0
while x > 0:
result += self.sums[x]
x -= self.low_bit(x)
return result
class Solution(object):
def reversePairs(self, nums):
"""
:param nums: [int]
:return: int
"""
nums2 = [x * 2 for x in nums]
dmap = {v: k for k, v in enumerate(sorted(set(nums + nums2)), start=1)}
fenwick = FenwickTree(len(dmap))
ans = 0
for n in nums2[::-1]:
ans += fenwick.get_sum(dmap[n/2]-1)
fenwick.add(dmap[n], 1)
return ans
它的做法是将数组里乘以2的值对应的下标计算出来,注意需要进行排序,这样才能保证后面BIT获取sum的时候是正确的,然后循环从后面开始是因为求的是逆序对,这样设置的时候则从后面开始设置,然后获取的sum函数意为计算nums中的值所在树中的位置前面存在多少个比n*2要大的值,然后设置的时候要设置nums2中的值,因为题目要求的就是比nums2的值要大的个数。
又或者都统一起来,将获取的index和设置的index都为nums中的值或许更容易理解一些,如下:
import bisect
class Solution(object):
def reversePairs(self, nums):
"""
:param nums: [int]
:return: int
"""
nums2 = sorted([x * 2 for x in nums])
n = len(nums2)
fenwick = FenwickTree(n)
order, binary_order = {}, {}
for i in range(n):
binary_order[i] = bisect.bisect_left(nums2, nums[i]) # num中的值在nums2中的位置
order[nums2[i]/2] = i+1 # nums中的值对应的位置
ans = 0
for i in range(n-1, -1, -1):
ans += fenwick.get_sum(binary_order[i]) # 获取前面存在多少个数
fenwick.add(order[nums[i]], 1) # 设置num的位置
return ans
[LeetCode] Reverse Pairs 翻转对的更多相关文章
- [LeetCode] 493. Reverse Pairs 翻转对
Given an array nums, we call (i, j) an important reverse pair if i < j and nums[i] > 2*nums[j] ...
- [LintCode] Reverse Pairs 翻转对
For an array A, if i < j, and A [i] > A [j], called (A [i], A [j]) is a reverse pair.return to ...
- LeetCode -Reverse Pairs
my solution: class Solution { public: int reversePairs(vector<int>& nums) { int length=num ...
- [LeetCode] Reverse String 翻转字符串
Write a function that takes a string as input and returns the string reversed. Example: Given s = &q ...
- [LeetCode] Reverse Integer 翻转整数
Reverse digits of an integer. Example1: x = 123, return 321 Example2: x = -123, return -321 click to ...
- 493 Reverse Pairs 翻转对
给定一个数组 nums ,如果 i < j 且 nums[i] > 2*nums[j] 我们就将 (i, j) 称作一个重要翻转对.你需要返回给定数组中的重要翻转对的数量.示例 1:输入: ...
- [Swift]LeetCode493. 翻转对 | Reverse Pairs
Given an array nums, we call (i, j) an important reverse pair if i < j and nums[i] > 2*nums[j] ...
- [LeetCode] Reverse Words in a String II 翻转字符串中的单词之二
Given an input string, reverse the string word by word. A word is defined as a sequence of non-space ...
- [LeetCode] 190. Reverse Bits 翻转二进制位
Reverse bits of a given 32 bits unsigned integer. For example, given input 43261596 (represented in ...
随机推荐
- MySQL数据库引擎介绍、区别
数据库引擎介绍 MySQL数据库引擎取决于MySQL在安装的时候是如何被编译的.要添加一个新的引擎,就必须重新编译MYSQL.在缺省情况下,MYSQL支持三个引擎:ISAM.MYISAM和HEAP.另 ...
- SSH复用代码最终版
web.xml文件 <?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="h ...
- 交互模式下测试python代码及变量的四则运算
在交互模式下,python代码可以立即执行,所以这很方便我们进行代码测试 1.命令窗口,输入python (如果没配置环境变量则需带python安装目录的绝对路径) >>> 这个就是 ...
- 适用初学者:vue2.0构建单页应用最佳实战
参考:https://segmentfault.com/a/1190000007630677 自己gitHub项目地址:https://github.com/shixiaoyanyan/vue-wor ...
- MySQL binlog 的恢复操作
测试出有个问题:mysqlbinlog 不加任何参数 恢复整个binlog 日志文件发现里面有这个操作 SET @@SESSION.GTID_NEXT 的操作, 如果需要恢复文件的时候就需要把他过 ...
- 初入ubuntu
登入root :su root 安装 vim: sudo apt-get install vim 安装 gcc(g++):sudo apt-get install gcc(g++) 非常实用的修改分辨 ...
- WaitAll 和 WhenAll 的使用及区别
用过.net 异步编程的同学都知道,比以前的多线程编程实现起来真的方便很多,今天把WaitAll和WhenAll这两种编程方式回顾总结一下(当然WaitAny.WhenAny是一样的操作) 1:Wai ...
- Spring-Boot:Spring Cloud构建微服务架构
概述: 从上一篇博客<Spring-boot:5分钟整合Dubbo构建分布式服务> 过度到Spring Cloud,我们将开始学习如何使用Spring Cloud 来搭建微服务.继续采用上 ...
- Android开发之基于监听的事件处理
在Android 应用开发过程中,常用监听事件如下:(1) ListView事件监听setOn ItemSelectedListener:鼠标滚动时触发setOnItemClickListener: ...
- html表格宽度设置失效
问题描述: 我在写一个网页table时,table宽度超过了我预想的宽度,我想把它设置小一点,但总是没效果.改到怀疑人生!代码如下: 经过多次调试后发现一个问题,table可以改变大小,但是会有一个最 ...