算法题中常见给定任意一个组合,输出所有的排列
如leetcode:https://leetcode-cn.com/problems/permutation-i-lcci/
无重复字符串的排列组合。编写一种方法,计算某字符串的所有排列组合,字符串每个字符均不相同。
示例1:
输入:S = “qwe”
输出:[“qwe”, “qew”, “wqe”, “weq”, “ewq”, “eqw”]
示例2:
输入:S = “ab”
输出:[“ab”, “ba”]
全排列算法是对数组中每个元素,依次与其他元素进行交换,然后将得到的排列放入列表参与下次迭代的过程,直到最后遍历所有元素完成交换后,得到全排列结果。这里要注意对于有重复的元素需要进行去重,简单的方式是将结果集放入set中。
以上述题为例,代码如下:
import java.util.ArrayList;
import java.util.List;
class Solution {
public String[] permutation(String S) {
List<String> resultList = new ArrayList<>();
resultList.add(S);
for(int i=0;i<S.length();i++){ // 从第0位开始,将list中将每个元素取出,和后面每一位做交换,放入list
int size = resultList.size();
for(int j=i+1;j<S.length();j++){ // 从i+1开始,每一位与i交换
for(int index=0;index<size;index++) // 将list中每个元素都进行该操作
resultList.add(swap(resultList.get(index),i,j));
}
}
return resultList.toArray(new String[0]); // 注意此处的转换方式
}
public String swap(String s, int i, int j){
char[] chars = s.toCharArray();
chars[i]^=chars[j];
chars[j]^=chars[i];
chars[i]^=chars[j];
return String.valueOf(chars);
}
}
拓展:找到下一个排列
leetcode:https://leetcode-cn.com/problems/next-permutation/
实现获取下一个排列的函数,算法需要将给定数字序列重新排列成字典序中下一个更大的排列。
如果不存在下一个更大的排列,则将数字重新排列成最小的排列(即升序排列)。
必须原地修改,只允许使用额外常数空间。
以下是一些例子,输入位于左侧列,其相应输出位于右侧列。
1,2,3 → 1,3,2
3,2,1 → 1,2,3
1,1,5 → 1,5,1
算法思想是从右向左找到第一个降序(a[i]<a[i+1])的位置,然后从该位置向右扫描到a[j]>a[i]&&a[j+1]<a[i]的位置,交换二者的元素,然后逆序下标i右侧位置的全部元素即可。
过程如动画所示:
代码如下:
import java.util.Arrays;
class Solution {
public void nextPermutation(int[] nums) {
if(nums.length==0) return;
int p=nums.length-2;
while(p>=0 && nums[p]>=nums[p+1]) p--;
if(p==-1){
Arrays.sort(nums);
return;
}
int r=p+1;
while(r<nums.length && nums[r]>nums[p]) r++;
r--;
nums[p]^=nums[r];
nums[r]^=nums[p];
nums[p]^=nums[r];
int l=p+1;
r=nums.length-1;
while(l<r){
nums[l]^=nums[r];
nums[r]^=nums[l];
nums[l]^=nums[r];
l++;
r--;
}
}
}