[leetcode]31.Next Permutation(Java实现)
2017-06-20 09:49
288 查看
测试地址:https://leetcode.com/problems/next-permutation/#/description
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.
Subscribe to see which companies asked this question.
题意(目的是找到比当前排序大1的新排序)
寻找比当前排列顺序大的下一个排列。
因为降序序列是没法变的更大的,所以从后往前找到第一个升序对的位置。
然后就存在调整大小排列顺序的可能,从后往前找到比当前位置大的元素,交换之。
当前位置后面的元素还是降序排列,将他们反转得到最小顺序排列。其实就是原来当前位置元素后面是最大的排列,而交换后的新元素之后是最小的排列,他们就是相邻的顺序。
当不存在升序,则当前排列是最大排列,只要旋转整个序列变成最小排列。
找给定序列的下一个字典序中的序列。
思想:
1、从右往左找第一个不满足升序的数,记该数下标为i;
2、从右往左找第一个比该数大的数,记下标味j;
3、交换两数:swap(num[i],num[j]);
4、将下标i+1到最后的数字反转;
网上寻找的另一个解释:
首先我们必须了解什么是“下一个”排列组合。考虑三个字符所组成的序列{a,b,c}。
这个序列有六个可能的排列组合:abc,acb,bac,bca,cab,cba。这些排列组合根据less-than操作符做字典顺序(lexicographical)的排序。也就是说,abc名列第一,因为每一个元素都小于其后的元素。acb是次一个排列组合,因为它是固定了a(序列内最小元素)之后所做的新组合。
同样道理,那些固定b(序列中次小元素)而做的排列组合,在次序上将先于那些固定c而做的排列组合。以bac和bca为例,bac在bca之前,因为次序ac小于序列ca。面对bca,我们可以说其前一个排列组合是bac,而其后一个排列组合是cab。序列abc没有“前一个”排列组合,cba没有“后一个”排列组合。
next_permutation()会取得[first,last)所标示之序列的下一个排列组合,如果没有下一个排列组合,便返回false;否则返回true。这个算法有两个版本。版本一使用元素型别所提供的less-than操作符来决定下一个排列组合,版本二则是以仿函数comp来决定。
Java code:
public void nextPermutation(int[] nums) {
if (nums == null || nums.length < 2)
return;
int index = nums.length - 1;
while (index > 0) {
if (nums[index - 1] < nums[index])
break;
index--;
}
// index为0,说明该数组是完全递减的
if (index == 0)
reverseSort(nums, 0, nums.length - 1);
else {
// 说明存在递增序列
index--;
int n = nums.length - 1;
while (true) {
if (nums
> nums[index])
break;
n--;
}
swap(nums, index, n);
reverseSort(nums, index + 1, nums.length - 1);
}
}
/*
* 将数组逆序排列
*/
private void reverseSort(int[] nums, int start, int end) {
for (int i = start; i < (start + end + 1) / 2; i++)
swap(nums, i, end - i + start);
}
/*
* 交换数组中任意两个元素位置
*/
private void swap(int[] nums, int i, int j) {
int temp = nums[i];
nums[i] = nums[j];
nums[j] = temp;
}
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
Subscribe to see which companies asked this question.
题意(目的是找到比当前排序大1的新排序)
寻找比当前排列顺序大的下一个排列。
因为降序序列是没法变的更大的,所以从后往前找到第一个升序对的位置。
然后就存在调整大小排列顺序的可能,从后往前找到比当前位置大的元素,交换之。
当前位置后面的元素还是降序排列,将他们反转得到最小顺序排列。其实就是原来当前位置元素后面是最大的排列,而交换后的新元素之后是最小的排列,他们就是相邻的顺序。
当不存在升序,则当前排列是最大排列,只要旋转整个序列变成最小排列。
找给定序列的下一个字典序中的序列。
思想:
1、从右往左找第一个不满足升序的数,记该数下标为i;
2、从右往左找第一个比该数大的数,记下标味j;
3、交换两数:swap(num[i],num[j]);
4、将下标i+1到最后的数字反转;
网上寻找的另一个解释:
首先我们必须了解什么是“下一个”排列组合。考虑三个字符所组成的序列{a,b,c}。
这个序列有六个可能的排列组合:abc,acb,bac,bca,cab,cba。这些排列组合根据less-than操作符做字典顺序(lexicographical)的排序。也就是说,abc名列第一,因为每一个元素都小于其后的元素。acb是次一个排列组合,因为它是固定了a(序列内最小元素)之后所做的新组合。
同样道理,那些固定b(序列中次小元素)而做的排列组合,在次序上将先于那些固定c而做的排列组合。以bac和bca为例,bac在bca之前,因为次序ac小于序列ca。面对bca,我们可以说其前一个排列组合是bac,而其后一个排列组合是cab。序列abc没有“前一个”排列组合,cba没有“后一个”排列组合。
next_permutation()会取得[first,last)所标示之序列的下一个排列组合,如果没有下一个排列组合,便返回false;否则返回true。这个算法有两个版本。版本一使用元素型别所提供的less-than操作符来决定下一个排列组合,版本二则是以仿函数comp来决定。
Java code:
public void nextPermutation(int[] nums) {
if (nums == null || nums.length < 2)
return;
int index = nums.length - 1;
while (index > 0) {
if (nums[index - 1] < nums[index])
break;
index--;
}
// index为0,说明该数组是完全递减的
if (index == 0)
reverseSort(nums, 0, nums.length - 1);
else {
// 说明存在递增序列
index--;
int n = nums.length - 1;
while (true) {
if (nums
> nums[index])
break;
n--;
}
swap(nums, index, n);
reverseSort(nums, index + 1, nums.length - 1);
}
}
/*
* 将数组逆序排列
*/
private void reverseSort(int[] nums, int start, int end) {
for (int i = start; i < (start + end + 1) / 2; i++)
swap(nums, i, end - i + start);
}
/*
* 交换数组中任意两个元素位置
*/
private void swap(int[] nums, int i, int j) {
int temp = nums[i];
nums[i] = nums[j];
nums[j] = temp;
}
相关文章推荐
- [编写高质量代码:改善java程序的151个建议]建议31-在接口中不要存在实现代码
- leetcode Length of Last Word java实现
- 169 Majority Element [LeetCode Java实现]
- java (31) - 序列化实现深克隆
- java学习笔记—使用HttpSession实现QQ的访问记录(31)
- [零基础学JAVA]Java SE应用部分-31.Java IO操作(05)IO操作实例讲解之实现简单MIS 推荐
- LeetCode中Count Primes的java实现
- JAVA学习笔记31——Map接口+Map常见方法+模拟实现Map(低级版和高级版)
- 【Leetcode】Reverse Words in a String JAVA实现
- LeetCode中的Valid Palindrome用Java实现
- Leetcode平台上的TwoSum题目用Java哈希表实现
- LeetCode 之 LRU Cache Java实现
- LeetCode OJ平台上Binary Tree Inorder Traversal题目使用java堆栈方式实现
- 好记性不如烂笔头31-java应用中的敏感词过滤实现(3)
- 【Leetcode】Insertion Sort List JAVA实现
- [编写高质量代码:改善java程序的151个建议]建议31-在接口中不要存在实现代码
- Leetcode OJ平台上的Binary Tree Preorder Traversal题目用java ArrayDeque实现
- leetcode题--Java实现
- 153.Find Minimum in Rotated Sorted Array [LeetCode Java实现]
- LeetCode中的Isomorphic Strings 的java实现