【算法】全排列算法

算法題中常見給定任意一個組合,輸出所有的排列
如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--;
        }
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章