leetcode384.打乱数组——洗牌算法

384. 打乱数组

Difficulty: 中等

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

示例:

// 以数字集合 1, 23 初始化数组。
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();

Solution

只有一行的洗牌算法,高纳德大神发明的,很简洁。
不过rand()函数产生的随机数有一点争议,可能不均匀。这里认为rand()是无偏的。

真正意义上的随机数(或者随机事件)在某次产生过程中是按照实验过程中表现的分布概率随机产生的,其结果是不可预测的,是不可见的。而计算机中的随机函数是按照一定算法模拟产生的,其结果是确定的,是可见的。我们可以这样认为这个可预见的结果其出现的概率是100%。所以用计算机随机函数所产生的“随机数”并不随机,是伪随机数。
计算机的伪随机数是由随机种子根据一定的计算方法计算出来的数值。所以,只要计算方法一定,随机种子一定,那么产生的随机数就是固定的。
只要用户或第三方不设置随机种子,那么在默认情况下随机种子来自系统时钟。
Python的这个库在底层使用通用的算法,经过长久的考验,可靠性没得说,但绝对不能用于密码相关的功能。

for i in range(len(L)-1,-1,-1):
	swap(L[i],L[rand(0,i)])//rand()产生[0,i]间的随机数,注意包括i

解法(发现代码速度慢可能是import的东西多,带着copy库就垫底,去掉后速度内存就是平均水平了):

class Solution(object):

    def __init__(self, nums):
        """
        :type nums: List[int]
        """
        self.nums=nums
        self.re=[i for i in nums]
        

    def reset(self):
        """
        Resets the array to its original configuration and return it.
        :rtype: List[int]
        """
        self.nums=[i for i in self.re]
        return self.nums

    def shuffle(self):
        """
        Returns a random shuffling of the array.
        :rtype: List[int]
        """
        nums=self.nums
        for i in range(len(nums)-1,-1,-1):
            a=random.randint(0,i)
            nums[i],nums[a]=nums[a],nums[i]
        return self.nums


# Your Solution object will be instantiated and called as such:
# obj = Solution(nums)
# param_1 = obj.reset()
# param_2 = obj.shuffle()

猜你喜欢

转载自blog.csdn.net/qq_45268474/article/details/108453314