【每日一题】31. Next Permutation

题目描述

Implement next permutation, which rearranges numbers into the lexicographically next greater permutation of numbers.

If such arrangement is not possible, it must rearrange it as the lowest possible order (ie, sorted in ascending order).

The replacement must be in-place and use only constant extra memory.

Here are some examples. Inputs are in the left-hand column and its corresponding outputs are in the right-hand column.

1,2,3` → `1,3,2`
`3,2,1` → `1,2,3`
`1,1,5` → `1,5,1

实现获取下一个排列的函数,算法需要将给定数字序列重新排列成字典序中下一个更大的排列。

如果不存在下一个更大的排列,则将数字重新排列成最小的排列(即升序排列)。

必须原地修改,只允许使用额外常数空间。

以下是一些例子,输入位于左侧列,其相应输出位于右侧列。

题解

首先想到的是,按顺序生成当前数组所有可能的排列组合,然后根据当前排列组合在其中的位置,如果是最后一个,返回第一个;否则,返回所在位置的下一个排列。为了保证不同排列符合题目的顺序,在生成所有组合之前,先进行升序排序,然后再进行排列。–但是这种情况,时间复杂度太高,而且不满足题目要求的空间复杂度要求

所以想到,根据上述的排列过程找出规律,根据给出的排列情况,直接生成下一个排列。

比如,对于数组1,2,3,4,5,下一个排列应该是1,2,3,5,4,下一个应该是1,2,4,3,5.变动的情况先发生在末尾,在以1,2,3,4之后只有一个5,下一个排列,应该保持1,2,3不动,整体变成1,2,3,5,4;

  1. 从后往前,先找到第一个不是降序排序的数字的下标;
  2. 如果下标<0,说明这个排列应该是最后一个,返回全序列的升序排序结果;
  3. 如果不为0,在这个元素之后找到第一个比它大的数字的下标,两者交换,对后续子数组做升序排序即可。

代码:

class Solution {
public:
    void nextPermutation(vector<int>& nums) {
        # 1,2,4,3,0
        if (nums.empty()) return;
        int size = nums.size(), i = size - 2, j = size - 1;
        
        while (i>=0 && nums[i] >= nums[i+1]) i--;
        
        if (i >= 0){
            while (nums[j] <= nums[i]) j--;
            swap(nums[i], nums[j]);
        }
        reverse(nums.begin()+i+1, nums.end());
    }
};

感觉说的不够清晰~

Reference

https://www.cnblogs.com/grandyang/p/4428207.html

向大佬学习


欢迎关注公众号,一起学习

### 如何在 `np.random.permutation` 中设置随机数种子 为了确保每次运行程序时生成的结果一致,可以通过设置随机数种子来实现这一目标。以下是关于如何在使用 `np.random.permutation` 时设置随机数种子的具体方法。 #### 设置随机数种子的方法 在 NumPy 的 `random` 模块中,可以调用 `np.random.seed(seed_value)` 来设定随机数生成器的种子[^2]。一旦设置了种子值,在后续执行任何依赖于随机性的操作(如 `np.random.permutation` 或其他随机函数)时,都会基于相同的初始状态生成可重复的结果。 #### 示例代码 下面是一个完整的示例,展示如何通过设置种子值使 `np.random.permutation` 返回相同的结果: ```python import numpy as np # 设置随机数种子 np.random.seed(42) # 使用 np.random.permutation 对列表进行随机排序 result = np.random.permutation([1, 2, 3, 4, 5]) print(result) # 输出: [3 2 5 1 4] ``` 如果再次运行此代码片段而不更改种子值,则会得到完全一样的结果 `[3 2 5 1 4]`。这是因为随机数生成器的状态被固定下来了。 需要注意的是,当不显式指定种子时,默认情况下 NumPy 随机数生成器会在内部选取一个不可预测的时间戳作为默认种子值,因此每次运行可能会获得不同的排列顺序。 另外值得注意的一点是,虽然这里讨论的重点在于 `np.random.permutation` 方法的应用场景及其与种子的关系,但实际上整个 NumPy 库中的所有涉及随机化的功能都遵循同样的原则——即只要提前设定了全局范围内的种子(`np.random.seed`)之后再调用任意数量次此类函数均能重现之前产生的数据模式[^3]。 #### 更多扩展应用实例 对于更复杂的案例来说,比如希望打乱一个多维数组或者仅需部分元素被打散重排而不是整体改变位置关系的情形下,也可以利用类似的逻辑完成任务: ```python import numpy as np # 设定固定的随机数种子以便验证一致性 np.random.seed(42) multi_dim_array = np.arange(16).reshape((4, 4)) shuffled_rows = multi_dim_array[np.random.permutation(multi_dim_array.shape[0])] print(shuffled_rows) ``` 在这个例子当中,我们先创建了一个四行四列大小填充连续整数值构成二维矩阵;接着借助 `np.random.permutation()` 获取到重新安排后的索引序列作用于原始对象之上从而实现了按照行维度独立洗牌的效果而保持每行列内相对布局不变特性[^4]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值