- 921. Minimum Add to Make Parentheses Valid 使括号有效的最少添加
- 915. Partition Array into Disjoint Intervals 分割数组
- 932. Beautiful Array 漂亮数组
- 940. Distinct Subsequences II 不同的子序列 II
题目地址:https://leetcode.com/problems/next-permutation/description/
Implement next permutation
, which rearranges numbers into the lexicographically next greater permutation of numbers.
Ifsuch arrangement is not possible, it must rearrange it as the lowest possible order (ie, sorted in ascending order).
Thereplacement 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 7 4 3 1
下一个排列为:
1 3 1 2 4 7
观察可以发现,再给出的数组中,2之后的数字都是降序排列的,我们把2后面第一个比2大的数字放到最前面,然后让3后面的数字升序排列。
简单思路的证明:从7开始是降序的,也就是说7 4 3 1不可能通过重新排列构成更大的数字。如果要得到next permutation,那么必须把2这个位置的数字给换掉才行,而且只能换成比2大的数字在才能使next permutation > current permutation.至于换成多大的数字,很明显的需要换成在2后面的数字中刚好比2大的数字,证明可以使用反证法来说明换成其他数字要么比当前数字小,要么大于正确的next permutation.
下面这个做法是先逆序再交换,本质和上面的证明一样:
如果从第n个数字到最后都是递减的并且第n-1个数字小于第n个,说明从第n个数字开始的这段序列是字典序组合的最后一个,在下一个组合中他们要倒序变为字典序第一个,然后从这段序列中找出第一个大于第n-1个数字的数和第n-1个数字交换就可以了。
举个栗子,当前组合为12431,可以看出431是递减的,同时4>2,这样我们把431倒序,组合就变为12134,然后从134中找出第一个大于2的数字和2交换,这样就得到了下一个组合13124。对于完全递减的组合例如4321在倒序之后就可以结束了。
代码如下:
class Solution(object):
def nextPermutation(self, nums):
"""
:type nums: List[int]
:rtype: void Do not return anything, modify nums in-place instead.
"""
n = len(nums)
i = n - 1
while i > 0 and nums[i] <= nums[i - 1]:
i -= 1
self.reverse(nums, i, n - 1)
if i > 0:
for j in range(i, n):
if nums[j] > nums[i-1]:
self.swap(nums, i-1, j)
break
def reverse(self, nums, i, j):
"""
contains i and j.
"""
for k in range(i, (i + j) / 2 + 1):
self.swap(nums, k, i + j - k)
def swap(self, nums, i, j):
"""
contains i and j.
"""
nums[i], nums[j] = nums[j], nums[i]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
也可以先进行交换,然后再翻转。比如Leetcode的这个解答方式:
C++代码如下:
class Solution {
public:
void nextPermutation(vector<int>& nums) {
const int N = nums.size();
int i = N - 2;
while (i >= 0 && nums[i] >= nums[i + 1]) --i;
int j = N - 1;
if (i >= 0) {
while (nums[j] <= nums[i]) --j;
swap(nums[i], nums[j]);
}
reverse(nums.begin() + i + 1, nums.end());
}
};
1 2 3 4 5 6 7 8 9 10 11 12 13 14
这个算我第一次觉得C++让人惊呆吧,有next_permutation函数,而且是原地操作。
class Solution {
public:
void nextPermutation(vector<int>& nums) {
next_permutation(nums.begin(), nums.end());
}
};
1 2 3 4 5 6
参考资料:
1、 https://leetcode.com/articles/next-permutation/;
2、 https://blog.csdn.net/tstsugeg/article/details/50261517;
3、 http://www.cnblogs.com/grandyang/p/4428207.html;
DDKK.COM 弟弟快看-教程,程序员编程资料站,版权归原作者所有
本文经作者:负雪明烛 授权发布,任何组织或个人未经作者授权不得转发
Numpy documentation在 np.random.permutation建议所有新代码使用 np.random.default_rng()来自随机生成器包。我在文档中看到,Random G
是否有任何已知的算法如何有效地生成具有附加限制的任何随机多集排列。 例子: 我有多个项目,例如:{1,1,1,2,2,3,3,3} ,以及一组限制性的集合,例如 { {3} , {1,2} , {1,
您将如何生成列表 b(1,6,8,3,9,5) 的所有可能排列包括不同长度的?例子: List a = [1,2,3] generateperms(a) 1,2,3 3,1,2 3,2,1 1,3,2
我不确定如何在限制范围内解决这个问题。 将“单词”视为大写字母 A-Z 的任何序列(不仅限于“字典单词”)。对于至少有两个不同字母的单词,还有其他单词由相同的字母组成但顺序不同(例如,STATIONA
题目地址:https://leetcode.com/problems/permutations/description/ 题目描述 Given a collection of distinct n
一行中有 n 个项目。我们必须在不能选择两个连续项目的限制下找到可以选择项目的方式数。 我试图用递归关系来做,但无法达到任何。请帮我解决问题。 最佳答案 在网上搜索后,我得到了上述问题的解决方案。 假
创建列表或集合的排列非常简单。我需要将函数应用于列表中所有元素的所有子集的每个元素,按照它们出现的顺序。例如: apply f [x,y] = { [x,y], [f x, y], [x, f y],
我遇到了一个看似简单的问题,有人可以帮忙吗? 我有两个列表 a和 b .我可以将列表的元素称为 a[i][j]其中 0
我正在将一个程序从 matlab 翻译成 Python。 matlab代码使用permute方法: B = PERMUTE(A,ORDER) rearranges the dimensions of
谜题 穷举一个数组中各个元素的排列 策略 减而治之、递归 JavaScript解 复制代码 代码如下:
题目地址:https://leetcode.com/problems/next-permutation/description/ 题目描述 Implement next permutation,
从我关于"Using SIMD AVX SSE for tree traversal" ive的另一个问题中,我得到了这个试图进行基准测试的代码。之前我没有对SIMD做任何事情,所以我对这种排列方式有
这段代码为我提供了长度为 x 的 n 值的所有可能组合,总和为 n。 function GETall_distri_pres($n_valeurs, $x_entrees, $combi_presen
如果我想找到列表的排列,我知道排列的数量由多项系数给出。例如,“MISSISSIPPI”有 11 个字母,“S”出现 4 次,“I”出现 4 次,“P”出现两次,“M”出现一次。因此“MISSISSI
我有一个伪代码,我已经将其翻译成java代码,但是每当我运行该代码时,我都会得到一个空的数组列表,但它应该给我一个随机的整数列表。这是伪代码: Algorithm 1. RandPerm(N) Inp
我想计算适合弗里德曼检验的分块设计的所有排列。考虑以下示例: thedata p dim(p) [1] 1295 12 R> head(p) [,1] [,2] [,3] [,4]
这与其说是编程问题,不如说是数学问题,但我认为这里的很多人都非常擅长数学! :) 我的问题是:给定一个 9 x 9 的网格(81 个单元格),其中必须包含数字 1 到 9,每个数字恰好出现 9 次,可
我有这个变量:message = "Hello World"我构建了一个对其进行洗牌的函数: def encrypt3(message,key): random.seed(key) l
以下程序使用 itertools.permutations 从列表中构造一个 URL。 def url_construct_function(): for i in range(1, len(
我有 36 个人和 6 张 table 。我想围绕每张 table 组成 6 个小组。然后再组成 6 个其他组,再组成 6 个其他组……直到每个人都遇到每个人,但没有人遇到两次。 到目前为止,我想出了
我是一名优秀的程序员,十分优秀!