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 翻转对的更多相关文章

  1. [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] ...

  2. [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 ...

  3. LeetCode -Reverse Pairs

    my solution: class Solution { public: int reversePairs(vector<int>& nums) { int length=num ...

  4. [LeetCode] Reverse String 翻转字符串

    Write a function that takes a string as input and returns the string reversed. Example: Given s = &q ...

  5. [LeetCode] Reverse Integer 翻转整数

    Reverse digits of an integer. Example1: x = 123, return 321 Example2: x = -123, return -321 click to ...

  6. 493 Reverse Pairs 翻转对

    给定一个数组 nums ,如果 i < j 且 nums[i] > 2*nums[j] 我们就将 (i, j) 称作一个重要翻转对.你需要返回给定数组中的重要翻转对的数量.示例 1:输入: ...

  7. [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] ...

  8. [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 ...

  9. [LeetCode] 190. Reverse Bits 翻转二进制位

    Reverse bits of a given 32 bits unsigned integer. For example, given input 43261596 (represented in ...

随机推荐

  1. jstl-初步认知

    JSTL是java提供的JSP标签库 1,在项目中加入 jsf-api.jar jsf-impl.jar jstl-1.2.jar 三个包 2, 如何在jsp页面引入标签库 使用 <@tagli ...

  2. 框架应用:Spring framework (四) - 事务管理

    事务控制 事务是什么?事务控制? 事务这个词最早是在数据库中进行应用,讲的用户定义的一个数据库操作序列,这些操作要么全做要么全不做,是一个不可分割的工作单位. 事务的管理是指一个事务的开启,内容添加, ...

  3. Struts 2.5 Filter mapping specifies an unknown filter name [struts2]

    问题一:java.util.concurrent.ExecutionException: org.apache.catalina.LifecycleException: Failed to start ...

  4. 九月 26, 2017 10:18:14 上午 com.sun.jersey.server.impl.application.RootResourceUriRules <init> 严重: The ResourceConfig instance does not contain any root resource classes.

    Tomcat启动错误:九月 26, 2017 10:18:14 上午 com.sun.jersey.server.impl.application.RootResourceUriRules <i ...

  5. 腾讯x5Webview取代原生android Webview

    一.官方地址: https://x5.tencent.com/tbs/ 二.不需要申请开发者,QQ直接登录,下载即可集成到项目中. 三.与原生的webview对比优势 1) 速度快:相比系统webvi ...

  6. 使用STS时遇到的小“麻烦”

    背景 今天尝试着用STS(Spring Tool Suite)建立了一个Maven webapp来做一个SpringMVC的小demo,在使用的过程中就遇到了一些小麻烦!!记录在此的目的,其一是为了自 ...

  7. Swiper.js使用方法

    <!DOCTYPE html> <html> <head>  ... <link rel="stylesheet" href=" ...

  8. java学习——java按值传递和按址传递

    先复制一个面试/笔试的题: 当一个对象被当作参数传递到一个方法后,此方法可改变这个对象的属性,并可返回变化后的结果,那么这里到底是值传递还是引用传递? 答案: 是值传递.Java语言的方法调用只支持参 ...

  9. 关于SSH

    SSH的英文全称是Secure Shell. 传统的网络服务程序,如:ftp和telnet在本质上都是不安全安全安全安全的,因为它们在网络上用明文传送口令和数据,别有用心的人非常容易就可以截获这些口令 ...

  10. poj1006中国剩余定理

    Biorhythms Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 103506   Accepted: 31995 Des ...