怒刷排列组合
在刷Leetcode
题目时,时常会看到一些大佬提出时间复杂度为O(1)
的题解,而我还在O(nm)
和O(n)
之间如此反复,细细品味,其实有一类题目是经常可以爆出O(1)
的解法的,这一类题目背后的数学依据就是排列组合。
顾名思义,排列即排列,组合即组合,排列组合主要是用来解决做一件事情有多少种方法或者某件事发生的概率是多少的问题。例如小明从家到学校可以选择步行、骑车、坐出租车。**问题1:**小明从家到学校有几种出行方式?**问题2:**小明从家到学校再返回家中,有几种出行方式?
针对上述的两个问题,其实是引入了排列组合问题中最基本的两个原理分类加法原理和分步乘法原理。
分类加法原理:做一件事情,完成它有N类方法,在第一类方法中有M1种不同的方法,第二类方法中有M2种不同的方法……第m类方法中有Mn种不同的方法,那么完成这件事共有M1+M2+…+Mn种不同的方法。
分步乘法原理:做一件事情,完成它需要n个步骤,做第一个步骤有M1种不同的方法,做第二个步骤有M2种不同的方法,第n个步骤有Mn种不同的方法,那么完成这件事共有M1 · M2 · … · Mn种不同的方法。
分类加法原理就是说一个任务被分成了几类,就有几项相加,本质是每一类方法均能独立的完成该任务;而分步乘法原理是分成几步,就有几项相乘,其本质是缺少任何一步均无法完成任务,每一步是不可缺少的环节。
有了对上述两个原理的理解,就可以更好的体会什么是排列、组合了,其定义如下:
排列:从n个不同的元素中任取m个(m≤n)元素,按照一定的顺序排列成一列,叫做从n个不同的元素中取出m个元素的一个排列。
组合:从n个不同的元素中任取m个(