全排列問題彙總

2021-08-21 13:52:22 字數 2761 閱讀 1646

目錄

無重複數的全排列問題

問題描述

思路分析

測試**

有重複數的全排列問題

問題描述

思路分析

測試**

下乙個排列問題

問題描述

思路分析

測試**

給定乙個沒有重複數字的序列,返回其所有可能的全排列。

輸入:[1,2,3]

輸出:[ [1,2,3], [1,3,2], [2,1,3], [2,3,1], [3,1,2], [3,2,1] ]

解決乙個演算法問題,我比較習慣於從基本的想法做起,我們先回顧一下我們自己是如何寫一組數的全排列的:1,3,5,9(為了方便,下面我都用數進行全排列而不是字元)。 

【1,3,5,9】(第乙個) 

首先保持第乙個不變,對【3,5,9】進行全排列。 

同樣地,我們先保持3不變,對【5,9】進行全排列。 

保持5不變,對9對進行全排列,由於9只有乙個,它的排列只有一種:9。 

故排列為【1,3,5,9】 

接下來5不能以5打頭了,5,9相互交換,得到 

【1,3,9,5】 

此時5,9的情況都寫完了,不能以3打頭了,得到

1,5,3,9

1,5,9,3

1,9,3,5

1,9,5,3

這樣,我們就得到了1開頭的所有排列,這是我們一般的排列數生成的過程。再接著是以3、5、9打頭,得到全排列。

public class permute_46 

permute(nums,list,0);

return lists;

}private static void permute(int nums, listlist, int index)

//i是從開始 i=index ;swap(,i)index相當於固定當前位置,在進行下一位的排列。

for(int i=index;i> lists=new arraylist<>();

lists=permute(nums);

for(listlist:lists)

system.out.println();}}

}

給定乙個可包含重複數字的序列,返回所有不重複的全排列。

輸入:[1,1,2]

輸出:[ [1,1,2], [1,2,1], [2,1,1] ]

這題和上面一題最主要的區別就是數字可以重複,如果按照原來的方法去做,肯定會出現重複的排列,那麼我們要做的就是去重,這裡我們先考慮一下,在前後交換的過程中,如果兩個元素相同的話,就不應該讓他們進行交換, 舉個例子:對於序列<1,1,2,3>。在dfs首遍歷時,1 作為首元素被加到list中,並進行後續元素的新增;那麼,當dfs跑完第乙個分支,遍歷到1 (第二個)時,這個1 不再作為首元素新增到list中,因為1 作為首元素的情況已經在第乙個分支中考慮過了,也就是說swap(num,0,1)這段**不應該發生,因此改進的測試**如下。 

public class permute_47 

permute(nums,list,0);

return lists;

}private static void permute(int nums, listlist, int index)

for(int i=index;i> lists=new arraylist<>();

lists=permute2(nums);

for(listlist:lists)

system.out.println();}}

}

實現獲取下乙個排列的函式,演算法需要將給定數字序列重新排列成字典序中下乙個更大的排列。

如果不存在下乙個更大的排列,則將數字重新排列成最小的排列(即公升序排列)。

必須原地修改,只允許使用額外常數空間。

以下是一些例子,輸入位於左側列,其相應輸出位於右側列。

1,2,31,3,2

3,2,11,2,3

1,1,51,5,1

我的整個思路是這樣的

1.從後往前找,依次比較nums[i]和nums[i+1],找到第乙個nums[i]2.如何找到要替換的數?同樣是從後往前遍歷,因為在第一步我們已經知道從i位置往後是遞減的, 所以我們從後往前找,找到第乙個比num[i]大的數就是最接近num[i]的數

3.將第二步找到的數和num[i]進行替換,是不是這麼一替換就完了呢?當然不是

4.由於i位置後面的數都是字典序最大的排列了,所以我們要將他換成最小的,這樣才是下乙個排列。

public class nextpermutation_31 

//找到了第乙個num[i]>num[i+1]的數

if(i>=0)

swap(nums,i,j);

reverse(nums,i+1,nums.length-1);

}else

}private static void reverse(int nums, int i, int j)

}public static void swap(int nums,int i,int j)

}

全排列問題

一 全排列問題演算法描述如下 舉例 345的全排列分別為 345 354 435 453 534 543,可見將整組數中的所有的數分別與第乙個數交換,這樣就總是在處理後n 1個數的全排列。又舉例 45的全排列有 45 54 可見將第乙個數分別與後面的數交換後輸出即為45的全排列。所以,對於乙個很長一...

全排列問題

題目描述814 全排列問題 鍵盤輸入n 1 n 10 個字元,輸出輸出其全排序。第一行為字元個數k,第二行為k個字元,不用空格隔開。輸出其每種排列佔一行,各字元間用一空格隔開。樣例輸入 3abc 樣例輸出 a b c a c b b a c b c a c b a c a b includeint ...

全排列問題

全排列就是從第乙個數字起 每個數分別與它後面的數字交換 用c 寫乙個函式,如 foo const char str 列印出 str 的全排列,如 abc 的全排列 abc,acb,bca,dac,cab,cba。第一種方法 用遞迴 不包含有重複數字或字元出現的情況 void swap char a,...