[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 ...
随机推荐
- Hibernate逆向工程【PowerDesigner、idea环境下】
为什么要使用逆向工程 由于我们每次编写Hibernate的时候都需要写实体,写映射文件.而且Hibernate的映射文件也容易出错.而逆向工程可以帮我们自动生成实体和映射文件,这样就非常方便了. 使用 ...
- Spring01-IOC
1,新建一个Java Project 导入如下jar包和apache-commons-logging包 2, 在src目录下创建一个beans.xml的配置文件,先加入schema spring-be ...
- A glimpse of Support Vector Machine
支持向量机(support vector machine, 以下简称svm)是机器学习里的重要方法,特别适用于中小型样本.非线性.高维的分类和回归问题.本篇希望在正篇提供一个svm的简明阐述,附录则提 ...
- Struts2的核心运行流程,原理图解
感觉很有必要制定一个计划,这样盲目的想到哪里写到哪里,不符合我大程序员的思维逻辑呀~~~嗯...那就从基本的开始吧,循循渐进,今天想到的先写上,不能浪费了,哈哈哈................... ...
- python pyinstaller打包exe暗坑1
环境 python2.7.9 win-xp 今天打包了一个小脚本,结果打开报错
- JSP内置对象的实验报告,页面登陆设计
JSP内置对象的实验报告 一.实验目的: 本实验的目的是让学生掌握怎样在JSP中使用内置对象request.page.response等. 二.实验要求: 编写四个JSP 页面login.jsp.Re ...
- 小符号反映大问题,Shell中下划线_与变量的关系。
之前写过一个根据日期和时间自动命名文件名的时候遇到一个问题. #! /bin/bash read -p "please input the filename:" filename ...
- yum软件管理器,及yum源配置
说到yum源就必须说到linux系统中特有的依赖关系问题,yum就是为了解决依赖关系而存在的.yum源就相当是一个目录项,当我们使用yum机制安装软件时,若需要安装依赖软件,则yum机制就会根据在yu ...
- unset与unlink
unset() -- 释放给定的变量 详见->http://www.kuqin.com/php5_doc/function.unset.html unlink() --删除文件 常用于用户 ...
- leetCode没那么难啦 in Java (二)
介绍 本篇介绍的是标记元素的使用,很多需要找到正确元素都可以将正确元素应该插入的位置单独放置一个标记来记录,这样可以达到原地排序的效果. Start 27.RemoveElement 删除指定元 ...