1. 程式人生 > 其它 >leetcode47 全排列 II

leetcode47 全排列 II

技術標籤:演算法刷題

leetcode47 全排列 II

本題含有重複元素的全排列問題,還是採用連續的同一個數取最後一個的去重方式,不同的是和前面的組合問題的去重稍有不同:

假如一個序列(已排序)是

1  1  2  2

首先明確一點,無論選1還是選2,交換後剩下的序列中2的連續性都不會受到影響。

但是1的連續性會受到影響,例如第一個數選2,交換後的序列就變成

2  1  2  1

這時第二個數的可選取序列就變成了

1  2  1

可見1不連續了。

那麼假如是組合問題,實際上當1不連續的時候,已經不會選1了,所選的數字全部是大於等於2的,這樣1可以直接被忽略,也就是說整個組合求解過程中所有可選取數在可選取序列中都是連續的。

假如是排列問題,就沒有選取的數字大於等於上一次選取的數字的約束條件了,也就是說有可能出現相同數字不連續的情況,因此去重不能再簡單的前後比較了,需要把該次考察的元素後面的所有元素都檢視一下,看有沒有和這個元素相等的元素。

class Solution {

    ArrayList<Integer> res = new ArrayList();
    List<List<Integer>> ans = new ArrayList();

    void swap(int[] nums,int a,int b){
        int tmp = nums[
a]; nums[a] = nums[b]; nums[b] = tmp; return ; } boolean hasElement(int[] nums,int start,int element){ for(int i = start;i < nums.length;i++){ if(nums[i] == element) return true; } return false; } void trackBack(int[] nums,
int pos){ if(pos == nums.length){ ans.add((List<Integer>) res.clone()); }else{ for(int i = pos;i < nums.length;i++){ if(hasElement(nums, i+1, nums[i])) continue; res.add(nums[i]); swap(nums, pos, i); trackBack(nums, pos+1); res.remove(res.size()-1); swap(nums, pos, i); } } } public List<List<Integer>> permuteUnique(int[] nums) { trackBack(nums, 0); return ans; } }

1ms 38.8MB