打乱数组,给你一个整数数组 nums ,设计算法来打乱一个没有重复元素的数组。打乱后,数组的所有排列应该是 等可能 的。

题记:

给你一个整数数组 nums ,设计算法来打乱一个没有重复元素的数组。打乱后,数组的所有排列应该是 等可能 的。

实现 Solution class:

Solution(int[] nums) 使用整数数组 nums 初始化对象
int[] reset() 重设数组到它的初始状态并返回
int[] shuffle() 返回数组随机打乱后的结果

示例 1:

输入
[“Solution”, “shuffle”, “reset”, “shuffle”]
[[[1, 2, 3]], [], [],[]]
输出
[null, [3, 1, 2], [1, 2, 3], [1, 3, 2]]

解释
Solution solution = new Solution([1, 2, 3]);
solution.shuffle(); // 打乱数组 [1,2,3] 并返回结果。任何 [1,2,3]的排列返回的概率应该相同。例如,返回 [3, 1, 2]
solution.reset(); // 重设数组到它的初始状态 [1, 2, 3] 。返回 [1, 2, 3]
solution.shuffle(); // 随机返回数组 [1, 2, 3] 打乱后的结果。例如,返回 [1, 3, 2]

提示:

  • 1 <= nums.length <= 50
  • -10 ^ 6 <= nums[i] <= 10 ^ 6
  • nums 中的所有元素都是 唯一的
  • 最多可以调用 104 次 reset 和 shuffle

题目来源:
作者:LeetCode
链接:https://leetcode.cn/leetbook/read/top-interview-questions-easy/xn6gq1/
来源:力扣(LeetCode)

官方答案:

使用mt_rand()函数来进行随机获取并交换对应的值,保证数组排列的等可能

代码如下:


class Solution {
   private $nums;
    /**
     * @param Integer[] $nums
     */
    function __construct($nums) {
        $this->nums = $nums;
    }

    /**
     * @return Integer[]
     */
     //重置数组
    function reset() {
        return $this->nums;
    }

    /**
     * @return Integer[]
     */
     //打乱数组
    function shuffle() {
        $data = $this->nums;
        for ($i = 0; $i < count($data); $i++){      //array(1,2,3)  数组的所有排列应该是 等可能 
            $j = mt_rand($i, count($data) - 1);     //(0,2)     i=0,j=1   =>(2,1,3)   i=0,j=1     =>(2,1,3)
            $this->swap($data, $i, $j);             //(1,2)     i=1,j=2   =>(2,3,1)   i=1,j=1     =>(2,1,3)
        }                                           //(2,2)     i=2,j=2   =>(2,3,1)   i=2,j=2     =>(2,1,3)
        return $data;
    }
    
    //交换两个数字的值
    private function swap(&$arr, $i, $j){
        $t = $arr[$i];
        $arr[$i] = $arr[$j];
        $arr[$j] = $t;
    }
}

/**
 * Your Solution object will be instantiated and called as such:
 * $obj = Solution($nums);
 * $ret_1 = $obj->reset();
 * $ret_2 = $obj->shuffle();
 */

其他答案:

打乱的时候clone一个新的数组,然后打乱这个新的数组即可。

打乱数组的时候会涉及到交换两个数字的值,除了常见的使用临时变量temp以外,还有其他几种方式,具体可以看下《交换两个数字的值》

public class Solution {
    private int[] nums;
    private Random random;

    public Solution(int[] nums) {
        this.nums = nums;
        random = new Random();
    }

    //重置数组,就是返回之前的数组
    public int[] reset() {
        return nums;
    }


    //打乱数组
    public int[] shuffle() {
        if (nums == null)
            return null;
        int[] a = nums.clone();//clone一个新的数组
        for (int j = 1; j < a.length; j++) {
            int i = random.nextInt(j + 1);
            swap(a, i, j);
        }
        return a;
    }

    //交换两个数字的值
//        private void swap(int[] a, int i, int j) {
//            if (i != j) {
//                a[i] ^= a[j];
//                a[j] ^= a[i];
//                a[i] ^= a[j];
//            }
//        }

    private void swap(int[] a, int i, int j) {
        if (i != j) {
            a[i] = a[i] + a[j];
            a[j] = a[i] - a[j];
            a[i] = a[i] - a[j];
        }
    }
}

来源:
作者:数据结构和算法
链接:https://leetcode.cn/leetbook/read/top-interview-questions-easy/xn6gq1/?discussion=Cn77ub
来源:力扣(LeetCode)

你可能感兴趣的:(PHP,算法,leetcode,数据结构,php)