陣列的排列
產生陣列的排列是一項常見的計算任務。給定一組不同元素,我們如何計算這些元素的所有可能排列?
遞歸演算法
排列產生的一種經典演算法採用遞歸。核心思想是將數組中的每個元素視為潛在的第一個元素,然後遞歸地排列剩餘元素以找到從第一個元素開始的所有可能組合:
// Recursive method for permutation generation public static void permute(int[] arr, int k) { for (int i = k; i < arr.length; i++) { // Swap elements at positions k and i Collections.swap(arr, k, i); // Recursively permute the remaining elements permute(arr, k + 1); // Restore original order of elements Collections.swap(arr, k, i); } if (k == arr.length - 1) { // Once all elements are permuted, print the current permutation System.out.println(Arrays.toString(arr)); } }
在此演算法中,參數k追蹤數組中的目前位置。最初,k 設定為 0,表示第一個元素。對於每個位置 k,它迭代剩餘的元素,將它們與位置 k 處的元素交換,並從位置 k 1 開始遞歸排列數組的其餘部分。這有效地考慮了從每個元素開始的所有可能的排列。
不同元素的非遞歸演算法
另一種非遞歸演算法此演算法適用於陣列中所有元素都不同的情況。它透過迭代交換元素來建立排列以實現特定模式:
for (int tail = arr.length - 1; tail > 0; tail--) { // Find the first decreasing element from the end if (arr[tail - 1] < arr[tail]) { // Find the last element greater than the decreasing element int s = arr.length - 1; while (arr[tail - 1] >= arr[s]) { s--; } // Swap the decreasing element with the greater element swap(arr, tail - 1, s); // Reverse the order of elements after the swap reverse(arr, tail); break; } }
該演算法從數組中元素的升序序列開始。它從右向左掃描數組,尋找第一個遞減的元素。一旦找到遞減的元素,它就會將其與數組尾部大於它的最小元素交換。最後,它反轉尾部元素的順序以獲得下一個排列。
相同元素的非遞歸演算法
如果陣列中的元素並不不同,使用HashMap 將元素對應到其索引可以處理潛在的重複:
// Create a HashMap to map elements to their indices Map<E, Integer> map = new HashMap<>(); for (int i = 0; i < arr.length; i++) { map.put(arr[i], i); } // Sort the array in ascending order Arrays.sort(arr); // Initialize the index array int[] ind = new int[arr.length]; for (int i = 0; i < arr.length; i++) { ind[i] = map.get(arr[i]); }
與正確的映射和索引,相同的非遞歸演算法可以產生所有排列,適當地處理重複元素。
以上是我們如何產生數組的所有可能排列,同時處理不同元素和非不同元素?的詳細內容。更多資訊請關注PHP中文網其他相關文章!