lc384 打乱数组

给你一个整数数组 nums ,设计算法来打乱一个没有重复元素的数组。

实现 Solution class:

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

示例:

输入
[“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 <= 200
-106 <= nums[i] <= 106
nums 中的所有元素都是 唯一的
最多可以调用 5 * 104 次 reset 和 shuffle

分析:
我们认为java中的伪随机函数是随机的。
注意随机类的运用:
Random rand = new Random();
rand.nextInt(4);//这个方法会返回 0…3之间的随机数

我们需要使用一个array数组存储这次返回的随机打乱数组,ori数组用来存储原始初始化的数组,这样才能reset()重置

对于array中的每个数,都是随机确定的,例如,对于第一个元素0,它就是随机从0…array.length - 1 中选取的,我们使用随机方法取得一个随机下标,赋值给array[0]即可 这里需要注意的是 对于下标为i的元素选取,需要从i…array.length - 1 中选出,因为i这个位置也有可能被选中

注意随机方法的书写

//初始化一个随机数生成器
    private Random rand = new Random();
    
//需要一个随机的返回的min-max-1 的随机下标
    public int randomIndex(int min,int max){
        
        //这个返回的值是  0...max - min - 1 + min 
        //0...max - 1
        return rand.nextInt(max-min) + min;
    }

代码如下

class Solution {

    //保存更新的这个数组
    private int [] array;
    
    //保存原始数组
    private int [] ori;

    //初始化一个随机数生成器
    private Random rand = new Random();

    //需要一个随机的返回的min-max-1 的随机下标
    public int randomIndex(int min,int max){
        
        //这个返回的值是  0...max - min - 1 + min 
        //0...max - 1
        return rand.nextInt(max-min) + min;
    }

    //写一个方法,交换array中的两个值
    public void swapa(int i ,int j){
        int temp = array[i];
        array[i] = array[j];
        array[j] = temp;
    }

    public Solution(int[] nums) {
        array = nums;

        //必须用克隆 用引用的话 如果array改变,ori也会改变
        ori = array.clone();
    }
    
    /** Resets the array to its original configuration and return it. */
    public int[] reset() {

        //赋值给 array 返回该值
        array = ori;

        //在克隆一份
        ori = ori.clone();

        //返回
        return array;
    }
    
    /** Returns a random shuffling of the array. */
    public int[] shuffle() {

        //对于 array中的元素,每个都随机更新其中的元素
        for(int i = 0;i < array.length;i++){
            
            //注意这里 第i个下标随机取出的范围 必须包括i,因为也有概率i留在原位置
            //注意这里传入的下标 即可,因为 swap中就是根据下标交换的
            swapa(i,randomIndex(i,array.length));
        }
        return array;
    }
}

/**
 * Your Solution object will be instantiated and called as such:
 * Solution obj = new Solution(nums);
 * int[] param_1 = obj.reset();
 * int[] param_2 = obj.shuffle();
 */

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,我能理解你的要求。以下是实现你要求的C++代码: ```c++ #include <iostream> using namespace std; void Ascending(int arr[], int n) { for (int i = 0; i < n; i++) { for (int j = i + 1; j < n; j++) { if (arr[i] > arr[j]) { int temp = arr[i]; arr[i] = arr[j]; arr[j] = temp; } } } } void MergeList(int arr1[], int arr2[], int arr3[], int n) { int i = 0, j = 0, k = 0; while (i < n && j < n) { if (arr1[i] < arr2[j]) { arr3[k++] = arr1[i++]; } else { arr3[k++] = arr2[j++]; } } while (i < n) { arr3[k++] = arr1[i++]; } while (j < n) { arr3[k++] = arr2[j++]; } } int main() { int* La = new int[5]; int* Lb = new int[5]; int* Lc = new int[10]; cout << "请输入La数组的5个元素(1-100):" << endl; for (int i = 0; i < 5; i++) { cin >> La[i]; } cout << "请输入Lb数组的5个元素(1-100):" << endl; for (int i = 0; i < 5; i++) { cin >> Lb[i]; } Ascending(La, 5); Ascending(Lb, 5); MergeList(La, Lb, Lc, 5); cout << "合并后的Lc数组为:" << endl; for (int i = 0; i < 10; i++) { cout << Lc[i] << " "; } cout << endl; delete[] La; delete[] Lb; delete[] Lc; return 0; } ``` 代码解释: 首先,我们使用 `new` 运算符动态分配内存创建了三个数组 `La`、`Lb` 和 `Lc`。 然后,我们使用 `cin` 输入了 `La` 和 `Lb` 两个数组的元素。 接着,我们调用了 `Ascending()` 函数,将 `La` 和 `Lb` 数组元素按照升序排序。 然后,我们调用了 `MergeList()` 函数,将排序后的 `La` 和 `Lb` 数组合并到 `Lc` 数组中。 最后,我们输出了合并后的 `Lc` 数组元素,并使用 `delete` 运算符释放了动态分配的内存。 注意:在创建动态数组后,一定要记得使用 `delete` 运算符释放内存,避免出现内存泄漏问题。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值