题目描述

给出两个整数 n 和 k,找出所有包含从 1 到 n 的数字,且恰好拥有 k 个逆序对的不同的数组的个数。

逆序对的定义如下:对于数组的第i个和第 j个元素,如果满i < j且 a[i] > a[j],则其为一个逆序对;否则不是。

由于答案可能很大,只需要返回 答案 mod 109 + 7 的值。

示例 1:

输入: n = 3, k = 0
输出: 1
解释:
只有数组 [1,2,3] 包含了从1到3的整数并且正好拥有 0 个逆序对。

示例 2:

输入: n = 3, k = 1
输出: 2
解释:
数组 [1,3,2] 和 [2,1,3] 都有 1 个逆序对。

说明:

n 的范围是 [1, 1000] 并且 k 的范围是 [0, 1000]。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/k-inverse-pairs-array
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

解题思路

在思考中发现一个规律,
假如现在要求 ni个数的 ki 个逆序对 (假设此时ki < ni),那么就是

  1. ni-1个数的ki个逆序对插入 ni 这个数字,不需要新增逆序对,将其添加到最后一位即可。即dp[ni-1][ki] += dp[ni-1][ki]

  2. ni-1个数的ki-1个逆序对插入 ni 这个数字,使得新增一个逆序对,只需要把 ni 插入到最后一个和倒数第二个数的中间就好了,这样ni只会和之前的最后一个数字形成逆序对。即dp[ni][ki] += dp[ni-1][ki-1]

  3. ni-1个数的ki-2个逆序对中,将ni插入到倒数第二个数和倒数第三个数的中间。ni和最后两个数字形成逆序对。即dp[ni][ki] += dp[ni-1][ki-2]


以此类推,可以得到

ki < ni 时,
f(ni)(ki) = f(ni-1)(0) + f(ni-1)(1) + f(ni-1)(2) + … + f(ni-1)(ki-1) + f(ni-1)(ki)

同理,由于 f(ni)(ki-1) = f(ni-1)(0) + … + f(ni-1)(ki-1)
得:f(ni)(ki) = f(ni)(ki-1) + f(ni-1)(ki)

但是还有特殊情况,ki 大于 ni 时,将ni插入f(ni-1)(0)、…、f(ni-1)(ki-ni)的第一位都不够满足 ki 的对数要求,那么需要将上述公式减去不能满足的个数
也就是f(ni)(ki) 应该从 f(ni-1)(ki-ni+1) 开始算起

即: f(ni)(ki) = f(ni-1)(ki-ni+1) + … + f(ni-1)(ki-1) + f(ni-1)(ki)
同理,f(ni)(ki-1) = f(ni-1)(ki-ni) + … + f(ni-1)(ki-1)
得:f(ni)(ki)= f(ni)(ki-1) - f(ni-1)(ki-ni) + f(ni-1)(ki)

综合两种情况,得到状态转移方程为:f(ni)(ki)= f(ni)(ki-1) - (ki>=ni?f(ni-1)(ki-ni):0) + f(ni-1)(ki)

反思错误

1、一开始没有考虑到 ki 大于 ni 的情况,导致数量过多
2、一开始使用 mod 求余,但是有出现数值为负数的情况,由于减的数量没有到达求余等级,但是加的数量求过余了,这样就变成负数了。后来使用加减来求余

Java代码

class Solution {private static final int MOD = (int)1e9 + 7;public int kInversePairs(int n, int k) {int[][] cnt = new int[2][k+1];cnt[0][0] = 1;// >0数字 0逆序对 -》 1组cnt[1][0] = 1;// 1数字 0逆序对 -》 1组// ni 几个数字,,ki 几组逆序对for(int ni=2;ni<=n;++ni) { // 从两个数字开始int cur = ni&1, pre = cur^1;for(int ki=1;ki<=k;++ki) { // 从有一个逆序对开始cnt[cur][ki] = cnt[cur][ki-1] + cnt[pre][ki] - (ki>=ni?cnt[pre][ki-ni]:0);if(cnt[cur][ki] >= MOD) {cnt[cur][ki] -= MOD;} else if (cnt[cur][ki]<0) {cnt[cur][ki] += MOD;}}}return cnt[n&1][k];}
}

执行结果

耗时:14ms,内存:35.3MB

[LeetCode][H0629]K个逆序对数组(Java)(动态规划)相关推荐

  1. LeetCode 629. K个逆序对数组(DP)

    文章目录 1. 题目 2. 动态规划 3. 优化的DP 1. 题目 给出两个整数 n 和 k,找出所有包含从 1 到 n 的数字,且恰好拥有 k 个逆序对的不同的数组的个数. 逆序对的定义如下:对于数 ...

  2. 629. K个逆序对数组

    629. K个逆序对数组 给出两个整数 n 和 k,找出所有包含从 1 到 n 的数字,且恰好拥有 k 个逆序对的不同的数组的个数. 逆序对的定义如下:对于数组的第i个和第 j个元素,如果满i < ...

  3. 【LeetCode 629】K个逆序对数组

    给出两个整数 n 和 k,找出所有包含从 1 到 n 的数字,且恰好拥有 k 个逆序对的不同的数组的个数. 逆序对的定义如下:对于数组的第i个和第 j个元素,如果满i < j且 a[i] > ...

  4. 【数据结构与算法】之深入解析“K个逆序对数组”的求解思路与算法示例

    一.题目要求 给出两个整数 n 和 k,找出所有包含从 1 到 n 的数字,且恰好拥有 k 个逆序对的不同的数组的个数. 逆序对的定义如下:对于数组的第 i 个和第 j 个元素,如果满 i < ...

  5. 【LeetCode笔记】剑指Offer 51. 数组中的逆序对(Java、分治)

    题目描述 多说无益-直接冲代码吧! 思路 && 代码 1. 暴力 O(n2n^2n2) 乍一看这题目,很难不直接用暴力法冲一冲(也就双层循环的事) 但是不出意料地超时啦-想一想,O(n ...

  6. XJTUOJ wmq的队伍(树状数组求 K 元逆序对)

    题目链接:http://oj.xjtuacm.com/problem/14/[分析]二元的逆序对应该都会求,可以用树状数组.这个题要求K元,我们可以看成二元的.我们先从后往前求二元逆序对数, 然后对于 ...

  7. 逆序对计数问题(java实现)

    一,相关定义 1.什么是逆序数? 在一个排列中,如果一对数的前后位置与大小顺序相反,即前面的数大于后面的数,那么它们就称为一个逆序.一个排列中逆序的总数就称为这个排列的逆序数. 例如:在序列 { 2, ...

  8. 蓝桥杯-逆序对(java)

    算法训练 逆序对   时间限制:1.0s   内存限制:256.0MB 问题描述 Alice是一个让人非常愉跃的人!他总是去学习一些他不懂的问题,然后再想出许多稀奇古怪的题目.这几天,Alice又沉浸 ...

  9. 算法笔记_065:分治法求逆序对(Java)

    目录 1 问题描述 2 解决方案 2.1 蛮力法 2.2 分治法(归并排序)   1 问题描述 给定一个随机数数组,求取这个数组中的逆序对总个数.要求时间效率尽可能高. 那么,何为逆序对? 引用自百度 ...

最新文章

  1. 成天说要删库跑路,这次真的有人干了
  2. 一句话总结卷积神经网络
  3. phpunit 单元测试案例--签到任务
  4. 自由职业者在合作之前要弄懂的15个问题
  5. jQuery |添加标签元素/内容
  6. NLP新秀:BERT的优雅解读
  7. 学计算机单招可以报那几个公立学校,为什么要选择公办单招学校,四川公办单招学校有哪些?...
  8. spring的Bean属性
  9. spring集成 log4j + slf4j
  10. Citrix 客户端登录出现wfshell.exe - 应用程序错误的解决方法
  11. Oracle-第一篇一些调优技巧
  12. mysql索引之联合索引
  13. 德芙网络营销策略ppt_看德芙网络营销策划经典案例,戳这里!
  14. 搭建Nexus3(maven私服搭建)
  15. SQL中笛卡尔积-cross join的用法
  16. PQ分区工具超详细图文教程
  17. 求最大值 最小值 下标 及格率 c语言,输入某班的C语言成绩,计算输出其及格率...
  18. larval中sessions的使用
  19. OpenResty学习——第七章 Web开发实战2——商品详情页
  20. java数组初始化赋值_Java数组的三种初始化方式

热门文章

  1. Mycat原理详解,Mycat 实现 MySQL 的读写分离(Mysql主从复制)
  2. 联想水滴 android,联想首款水滴全面屏!性能与时尚的完美结合,偶像级自拍体验...
  3. 联想服务器销售公司,安徽联想服务器硬盘_提升运维效率
  4. java基于微信小程序的寻医问药 医院预约挂号系统 uniapp小程序
  5. TensorFlow2中的常用API速查速记
  6. 马臣云:手写数字签名 创新金融信息化
  7. GenVisR绘制瀑布图/突变图谱
  8. AI二次开发C#图形项
  9. 中文版30种濒危动物碎片拼图
  10. Intel I210网卡