在計算機科學中,排列問題是一個經典的問題,涉及到對一組元素進行重新排列,以生成所有可能的排列組合。其中,”下一個排列”問題是一個常見的變體,要求我們找到給定排列的下一個字典序排列。本文將詳細介紹如何使用Java解決這個問題,并提供相應的代碼示例。
給定一個整數數組 nums
,表示一個排列,要求找到該排列的下一個字典序排列。如果當前排列已經是最大的排列,則返回最小的排列。
例如:
- 輸入:nums = [1,2,3]
- 輸出:[1,3,2]
nums = [3,2,1]
[1,2,3]
要解決這個問題,我們需要理解字典序排列的生成規則。字典序排列的生成遵循以下步驟:
從右向左查找第一個下降的元素:從數組的末尾開始,找到第一個滿足 nums[i] < nums[i+1]
的元素 nums[i]
。這個元素是我們可以進行交換的最小元素。
找到比 nums[i]
大的最小元素:在 nums[i]
的右側,找到比 nums[i]
大的最小元素 nums[j]
。
交換 nums[i]
和 nums[j]
:交換這兩個元素,使得 nums[i]
變為比原來大的最小元素。
反轉 nums[i+1]
到末尾的元素:將 nums[i+1]
到末尾的元素反轉,以確保這一部分是升序排列,從而得到最小的排列。
以下是使用Java實現上述思路的代碼:
public class NextPermutation {
public void nextPermutation(int[] nums) {
int i = nums.length - 2;
// 從右向左查找第一個下降的元素
while (i >= 0 && nums[i] >= nums[i + 1]) {
i--;
}
if (i >= 0) {
int j = nums.length - 1;
// 找到比 nums[i] 大的最小元素
while (j >= 0 && nums[j] <= nums[i]) {
j--;
}
// 交換 nums[i] 和 nums[j]
swap(nums, i, j);
}
// 反轉 nums[i+1] 到末尾的元素
reverse(nums, i + 1);
}
private void swap(int[] nums, int i, int j) {
int temp = nums[i];
nums[i] = nums[j];
nums[j] = temp;
}
private void reverse(int[] nums, int start) {
int i = start, j = nums.length - 1;
while (i < j) {
swap(nums, i, j);
i++;
j--;
}
}
public static void main(String[] args) {
NextPermutation solution = new NextPermutation();
int[] nums1 = {1, 2, 3};
solution.nextPermutation(nums1);
System.out.println(Arrays.toString(nums1)); // 輸出: [1, 3, 2]
int[] nums2 = {3, 2, 1};
solution.nextPermutation(nums2);
System.out.println(Arrays.toString(nums2)); // 輸出: [1, 2, 3]
int[] nums3 = {1, 1, 5};
solution.nextPermutation(nums3);
System.out.println(Arrays.toString(nums3)); // 輸出: [1, 5, 1]
}
}
查找第一個下降的元素:
nums[i] < nums[i+1]
的元素。如果找不到這樣的元素,說明當前排列已經是最大的排列,直接反轉整個數組即可。查找比 nums[i]
大的最小元素:
nums[i]
的右側,我們從數組的末尾開始,向前查找第一個比 nums[i]
大的元素 nums[j]
。交換元素:
nums[i]
和 nums[j]
,使得 nums[i]
變為比原來大的最小元素。反轉剩余部分:
nums[i+1]
到末尾的元素反轉,以確保這一部分是升序排列,從而得到最小的排列。n
是數組的長度。我們最多只需要遍歷數組兩次。通過上述步驟,我們可以有效地解決下一個排列的問題。這個問題不僅考察了我們對數組操作的理解,還考察了我們對字典序排列生成規則的掌握。希望本文的講解和代碼示例能夠幫助你更好地理解和解決這個問題。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。