问题
- 打乱一个没有重复元素的数组
常规暴力解法
-
讲数组的所有元素复制一份保存在一个ArrayList内,遍历数组,每次遍历生成一个在0到链表大小之间的随机数,将对应索引处的数组元素替换成链表中该随机数对应索引处的元素值,并从链表中移除该元素。
-
时间复杂度: O(n*n)
-
空间复杂度: O(n)
Fisher-Yates洗牌算法
思路
- 我们可以用一个简单的技巧来降低之前算法的时间复杂度和空间复杂度,那就是让数组中的元素互相交换,这样就可以避免掉每次迭代中用于修改列表的时间了。
算法
- Fisher-Yates 洗牌算法跟暴力算法很像。在每次迭代中,生成一个范围在当前下标到数组末尾元素下标之间的随机整数。接下来,将当前元素和随机选出的下标所指的元素互相交换 - 这一步模拟了每次从 “帽子” 里面摸一个元素的过程,其中选取下标范围的依据在于每个被摸出的元素都不可能再被摸出来了。此外还有一个需要注意的细节,当前元素是可以和它本身互相交换的 - 否则生成最后的排列组合的概率就不对了。
##完整代码
class Solution {
int