【算法】全排列算法

算法题中常见给定任意一个组合,输出所有的排列
如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--;
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值