LeetCode384-打乱数组

英文链接:https://leetcode.com/problems/shuffle-an-array/

中文链接:https://leetcode-cn.com/problems/shuffle-an-array/

题目详述

打乱一个没有重复元素的数组。

示例:

1
2
3
4
5
6
7
8
9
10
11
12
// 以数字集合 1, 2 和 3 初始化数组。
int[] nums = {1,2,3};
Solution solution = new Solution(nums);

// 打乱数组 [1,2,3] 并返回结果。任何 [1,2,3]的排列返回的概率应该相同。
solution.shuffle();

// 重设数组到它的初始状态[1,2,3]。
solution.reset();

// 随机返回数组[1,2,3]打乱后的结果。
solution.shuffle();

题目详解

  • 为了重设数组到它的初始状态,需要单独用一个数组保存一个初始状态。用另一个复制的数组来打乱。问题的关键在于怎么打乱一个数组。
  • 经典的 Fisher-Yates 洗牌算法可以打乱数组,它能保证等概率的生成全排列结果中的任意一种。从后往前遍历数组,每次随机生成一个区间下标,与当前下标的数进行交换(也可以从前后往后遍历,这时生成的随机值要加上对应的偏移量)。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
大专栏  LeetCode384-打乱数组s="line">23
24
25
26
27
28
29
30
31
32
33
public class  {

class Solution {
private int[] src;
private int[] arr;
private Random random;

public Solution(int[] nums) {
src = nums;
arr = Arrays.copyOf(src, src.length);
random = new Random();
}


public int[] reset() {
return src;
}

/** Returns a random shuffling of the array. */
public int[] shuffle() {
for (int i = arr.length - 1; i >= 0; --i) {
swap(i, random.nextInt(i + 1));
}
return arr;
}

private void swap(int i, int j) {
int tmp = arr[i];
arr[i] = arr[j];
arr[j] = tmp;
}
}
}

猜你喜欢

转载自www.cnblogs.com/liuzhongrong/p/12365548.html