LintCode 197. Permutation Index (Easy)

LintCode 198. Permutation Index II (Medium)

感觉这两道题主要考察计算排列组合的能力.

Permutation Index

举例:

123 -> 1
132 -> 2
213 -> 3
231 -> 4
312 -> 5
321 -> 6

以321为例进行分析:

首先考虑第一位3: 3右边比3小的数字有两个(1和2), 所以以1和2为首位的数字排在3xx的前面, 这样的数字有2 * 2! = 4个. 所以以3开头的数字至少排第5.

3已经考虑完, 看后面两位.

12 -> 1
21 -> 2

在321中, 2右边比2小的数字有一个(1), 所以以1为首位的数字排在2x的前面, 这样的数字有1 * 1! = 1个.

最后一个1, 只有一个数字, 排在它前面的数字是0个.

综上, 321前面排了5个数字, 所以它的Permutation Index是6.

按照这个思路, 对于从右数第iA[i](i = 0, 1, 2...), 若它的右边有k个数字小于A[i], 那么这一位就会在Permutation Index中贡献k * i!.

class Solution {
public:
/**
* @param A an integer array
* @return a long integer
*/
long long permutationIndex(vector<int>& A) {
int N = A.size();
long long index = 1;
long long mul = 1;
for (int i = N - 2; i >= 0; --i) {
int cnt = 0;
for (int j = i + 1; j < N; ++j) {
if (A[j] < A[i]) ++cnt;
}
index += cnt * mul;
mul *= N - i;
}
return index;
}
};

时间复杂度: O(n^2)

空间复杂度: O(1)

Permutation Index II

做完了Permutation Index我看了下九章的解答. 我去, 怎么这么复杂. 看了一半看不下去了, 然后发现九章上的Permutation Index II用的一样的解法, 说明九章只是把第二题的解法直接复制到第一题里了.

自己想这题花了好久好久, 顿感高中数学忘得差不多了(T_T).

举例:

11223 -> 1
11232 -> 2
11322 -> 3
12123 -> 4
12132 -> 5
12213 -> 6
12231 -> 7
12312 -> 8
12321 -> 9
13122 -> 10

考虑13122:

第一位1, 没有比1再小的数字了, 所以1开头的数字是从第一个开始的.

第二位3, 3右边比3小的数字有1和2.

  • 如果1和3互换位置, 后面三位将是数字2,2,3. 这三个数字的组合数是3! / 2! = 3个.
  • 如果2和3互换位置, 后面三位将是数字1,2,3. 这三个数字的组合数是3! = 6个.

所以因为第二位比3小(首位是1)而排在13xxx前面的数字有9个. 因此13xxx一定是从第10个开始的.

至此, 结合上一题, 已经能看出规律: 对于从右数第iA[i], 看它右边的每一个比A[i]小的数字, 假设A[j] < A[i] (j > i), 那么假想A[j]A[i]互换位置后, 计算右边的i-1个数字的组合数就是这A[j]贡献的. 要注意的是, A[i]右边可能有多个比A[i]小的重复数字, 这些数字只贡献一次.

class Solution {
private:
map<int, int> m;
long long fac(int num) {
long long n = 1;
while (num > 0) {
n *= num;
num--;
}
return n;
} long generateNum() {
long long num = 1;
for (auto it = m.begin(); it != m.end(); ++it) {
num *= fac(it->second);
}
return num;
}
public:
/**
* @param A an integer array
* @return a long integer
*/
long long permutationIndexII(vector<int>& A) {
int N = A.size();
if (N == 0) return 0;
m.clear();
long long index = 1;
for (int num : A) {
if (m.find(num) != m.end()) {
++m[num];
} else {
m[num] = 1;
}
}
for (int i = 0; i < N; ++i) {
set<int> s;
for (int j = i + 1; j < N; ++j) {
if (A[j] < A[i] && s.find(A[j]) == s.end()) {
m[A[j]]--;
index += fac(N - i - 1) / generateNum();
s.insert(A[j]);
m[A[j]]++;
}
}
m[A[i]]--;
if (m[A[i]] == 0) m.erase(A[i]);
}
return index;
}
};

时间复杂度: O(n^2) (至少. facgenerateNum的复杂度取决于输入.)

空间复杂度: O(n)

[OJ] Permutation Index的更多相关文章

  1. Permutation Index I & II

    Given a permutation which contains no repeated number, find its index in all the permutations of the ...

  2. Lintcode: Permutation Index II

    Given a permutation which may contain repeated numbers, find its index in all the permutations of th ...

  3. lintcode :Permutation Index 排列序号

    题目: 排列序号 给出一个不含重复数字的排列,求这些数字的所有排列按字典序排序后该排列的编号.其中,编号从1开始. 样例 例如,排列[1,2,4]是第1个排列. 解题: 这个题目感觉很坑的.感觉这只有 ...

  4. * 197. Permutation Index【LintCode by java】

    Description Given a permutation which contains no repeated number, find its index in all the permuta ...

  5. lintcode Permutation Index

    题目:http://www.lintcode.com/zh-cn/problem/permutation-index/ 排列序号 给出一个不含重复数字的排列,求这些数字的所有排列按字典序排序后该排列的 ...

  6. [LintCode]——目录

    Yet Another Source Code for LintCode Current Status : 232AC / 289ALL in Language C++, Up to date (20 ...

  7. 《R包的分类介绍》

    R分析空间数据(Spatial Data) R机器学习包(Machine Learning) R多元统计包(Multivariate Statistics) R药物(代谢)动力学数据分析包 R计算计量 ...

  8. R语言︱常用统计方法包+机器学习包(名称、简介)

    一.一些函数包大汇总 转载于:http://www.dataguru.cn/thread-116761-1-1.html 时间上有点过期,下面的资料供大家参考基本的R包已经实现了传统多元统计的很多功能 ...

  9. leetcode 22括号生成

    非常好的一道题.一开始的思想是这样的,先把n对括号按照某一顺序生成一个string,然后用全排列算法生成所有可能,然后利用stack写一段判断括号是否匹配的字符串,匹配的假如结果中.不过会超时.因为全 ...

随机推荐

  1. MVC小系列(十七)【自定义验证规则给下拉框】

    因为下拉框不支持验证,所以写一个attribute特性,让它继承ValidationAttributemvc的特性验证,很直接,无论是数据安全特性上还是页面表现上都不错,它的运行机制: 前台表单验证规 ...

  2. angularjs + springmvc 上传和下载

    jsp: <form ng-submit="uploadFile()" class="form-horizontal" enctype="mul ...

  3. Candence下对“跨页连接器(off-page connector)”进行批量重命名的方法

    parts.ports.alias等等均可以在“属性编辑器(Property Editor)”中进行查看编辑,并通过复制到Excel等表格软件来进行批量修改.之后再粘贴回去的方法进行批量编辑.但是“跨 ...

  4. Mybatis 学习历程

    MyBatis是一个支持普通SQL查询,存储过程和高级映射的优秀持久层框架. MyBatis消除了几乎所有的JDBC代码和参数的手工设置以及对结果集的检索封装. MyBatis可以使用简单的XML或注 ...

  5. zoj 1649 Rescue (BFS)(转载)

    又是类似骑士拯救公主,不过这个是朋友拯救天使的故事... 不同的是,天使有多个朋友,而骑士一般单枪匹马比较帅~ 求到达天使的最短时间,杀死一个护卫1 units time , 走一个格子 1 unit ...

  6. Windows下ANSI、Unicode、UTF8字符编码转换

    主意:输入字符串必须是以'\0'结尾,如果输入字符串没有以'\0'结尾,请手动设置,否则转换会有错误. unsigned int EncodeUtil::AnsiToUcs2( char* pAnsi ...

  7. Java内存模型JMM与可见性

    Java内存模型JMM与可见性 标签(空格分隔): java 1 何为JMM JMM:通俗地讲,就是描述Java中各种变量(线程共享变量)的访问规则,以及在JVM中将变量存储到内存和从内存中读取变量这 ...

  8. Hibernate的检索策略

    hibernate 的中的session依照load()和get()按照参数的制定OID(ObjctID)去加载一个持久化对象.另外Query.list()方法则按照HQL语句去加载持久化的对象. 以 ...

  9. Linux中的堡垒--iptables

    iptables的构成(四表五链)     表         filter:过滤数据包         nat :转换数据包的源或目标地址         mangle:用来mangle包,改变包的 ...

  10. 手机摇一摇效果-html5

    1.手机摇一摇效果实现 2.播放声音 <!DOCTYPE html> <html lang="en"> <head> <meta char ...