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, do not allocate 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

又一道permutation的题目,题目要求inplace,所以很明显,类似于permutation那种全部求出结果再查找的方法肯定不行,只有真正找到词典序的规律。记得之前组合数学课上曾经学过这种,当时怎么都没想明白书中给的方法,没想到这题结合举例分析,竟然想出了和书中方法完全一样的解法,甚为开心呐~

总体思路如下:

1.从前向后找一个严格递增的子序列,将递增子序列的最后一个i记为up。

2.因为up及之后的数字组成了一个非递增序列,所以改变后面的数字排序不能得到下一个更大的数字。所以需要修改的是up-1这个位上的数,即nums[up:]中比nums[up-1]大的最小值,也即将其修改为nums[up:]中最后一个比其大的数字,(因为是非递增序列)。找到这个index,交换nums[index],nums[up-1]

3.将nums[up:]逆序,其实是做一次升序排序,但是考虑交换nums[index],nums[up-1]后,nums[up:]依然为非递增序列,所以只要reverse就可以。

举个例子,7 2 5 3 3 1。先找到 up为2,则nums[up-1]为2,nums[up:] 中比2大的最小值为3,注意是取最后一个3,方便第3步直接reverse,获得增序排序。

交换数字之后成为 7 3 5 3 2 1,然后对5321做一个逆序,获得最终的排序为7 3 1 2 3 5。

可以看到最多扫描三次, up 为0时,直接reverse,扫描两次。空间复杂度为O(1),代码如下:

class Solution(object):
    def nextPermutation(self, nums):
        """
        :type nums: List[int]
        :rtype: void Do not return anything, modify nums in-place instead.
        """
        up = 0
        for i in xrange(1,len(nums)):
            if nums[i] > nums[i-1]:
                up = i
        if up == 0:
            nums.reverse()
        else:
            index = up
            for i in xrange(up,len(nums)):
               if nums[i] >  nums[up-1]:
                   index = i
            nums[up-1], nums[index] = nums[index], nums[up-1]
            for i in xrange((len(nums) - up)/2):
                nums[up + i], nums[len(nums)-1-i] = nums[len(nums)-1-i], nums[up+i]

 

转载于:https://www.cnblogs.com/sherylwang/p/5568452.html

资源下载链接为: https://pan.quark.cn/s/967a7e1a5d94 《东北大学应用数理统计2009—2020真题及个人答案解析》是一份极具价值的学习资料,对于准备东北大学应用数理统计课程考试的学生而言意义非凡。它涵盖了十二年的考试真题以及作者的详细答案解析,为学生提供了一个深入了解考试方向、复习要点和解题技巧的优质平台。 数理统计作为应用数学的重要分支,主要基于概率论理论,通过收集、分析、解释和呈现数据来解决实际问题。在东北大学的该课程中,学生需掌握诸多核心知识点,包括样本与总体、随机变量、期望值与方差、概率分布、假设检验、置信区间、线性回归等。 首先,样本与总体是统计学的基础概念。通过对样本的研究来推断总体特征,理解它们之间的关系及抽样分布的重要性至关重要。其次,随机变量是概率论的核心,无论是连续型还是离散型随机变量,掌握其概率密度函数或概率质量函数是进行统计推断的关键。期望值和方差分别反映随机变量的平均值和波动程度,帮助我们了解随机现象的中心趋势和稳定性。此外,常见的概率分布如均匀分布、正态分布、泊松分布、二项分布等,对于分析实际问题中的数据分布极为重要。假设检验是科研和决策中的重要环节,常用的T检验、Z检验、卡方检验和F检验等方法,能够帮助判断数据是否支持特定假设。置信区间则用于估计总体参数的不确定范围,其计算和解释是理解统计推断的关键。线性回归是预测和建模的常用方法,通过分析最佳拟合直线来揭示变量间的关系,而残差分析、多重共线性和模型选择等则是提升回归分析能力的重要方面。 在解答这些真题时,作者不仅检验了自己的知识掌握程度,还分享了个人的解题思路和策略。这些内容对于后来的学习者来说极具参考价值。通过深入研究这些真题和答案,学生可以熟悉考试的常见题型,把握出题老师的命题风格,并学会如何高效地组织和呈现答案。这份资料对于提升学生的数理统计理论水平和
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值