一網友離職後,突然收到前公司員工分配的任務,關鍵是人家都離職了,並且分配任務的人也不是他們之前部門的。這種事但凡正常人應該都做不出來,網友評論 先加錢在幹活 。
我之前離職之後收到幾個同事的訊息問有沒有時間,一起吃個飯,我感覺都已經走了,在回去吃飯有點不妥,最終還是沒去。該網友收到的訊息是有沒有時間幹點活,幹活可以,先發個大大的紅包,一切都好說。。。
網友評論:
--------------下面是今天的演算法題--------------
來看下今天的演算法題,這題是LeetCode的第31題:下一個排列。
問題描述
來源:LeetCode第31題
難度:中等
實作獲取下一個排列的函式,演算法需要將給定數位序列重新排列成字典序中下一個更大的排列(即,組合出下一個更大的整數)。如果不存在下一個更大的排列,則將數位重新排列成最小的排列(即升序排列)。
必須原地修改,只允許使用額外常數空間。
範例1:
輸入 :nums = [1,2,3]
輸出 :[1,3,2]
範例2:
輸入 :nums = [3,2,1]
輸出 :[1,2,3]
1 <= nums.length <= 100
0 <= nums[i] <= 100
問題分析
這題說的是計算數位序列重新排列成
字典序中下一個更大的排列
。舉個例子,比如數位213的下一個排列是231,231的下一個排列是312。
那麽這題的規律該怎麽找呢,我們來看這樣一組數位
[7,5,4,3,2]
這些數位從後往前都是升序的,無論怎麽調換位置都不可能獲得更大的排列。
再來看一組數位
[1,4,7,6,5,3,2]
從後往前看2→3→5→6→7是升序的,但7→4是降序的,我們只需要把4和7交換一下就可以獲得比原來更大的排列。但這裏要等一下,題中要求的是找出 比原來大的最小的排列 。交換4和7雖然比原來大,但不是最小的。實際上用5和4交換要比7和4交換更小。
所以這裏當我們從後往前找到第一個降序的數位之後(比如上面的4),我們還要從後往前找到第一個比降序數位大的值(比如上面的5),然後這兩個數位交換(比如上面的4和5交換)。
交換完之後(比如上面的交換之後是[1,5, 7,6,4,3,2 ]),這個排列肯定是比原來的大,因為5比4大,我們只需要讓5後面的排列數位最小即可。
因為5後面的數位[7,6,4,3,2]從 後往前是升序 的,我們只需要把他反轉即可,所以[1,4,7,6,5,3,2]的下一個排列是[1,5,2,3,4,6,7],畫個圖來加深一下理解。
JAVA:
publicvoidnextPermutation(int[] nums){
int left = nums.length - 2;
// 兩兩比較,從後面往前找第一個降序的
while (left >= 0 && nums[left] >= nums[left + 1])
left--;
// 如果陣列nums中的元素都是倒敘,那麽left就等於-1
if (left >= 0) {
int right = nums.length - 1;
// 從後面尋找第一個比nums[left]大的值
while (nums[right] <= nums[left])
right--;
swap(nums, left, right);
}
// 反轉後面升序的數位
reverse(nums, left + 1, nums.length - 1);
}
// 反轉子陣列[left,right]中的元素
privatevoidreverse(int[] nums, int left, int right){
while (left < right)
swap(nums, left++, right--);
}
// 交換陣列中的兩個數位
privatevoidswap(int[] nums, int left, int right){
int tmp = nums[left];
nums[left] = nums[right];
nums[right] = tmp;
}
C++:
public:
voidnextPermutation(vector<int> &nums){
int left = nums.size() - 2;
// 兩兩比較,從後面往前找第一個降序的
while (left >= 0 && nums[left] >= nums[left + 1])
left--;
// 如果陣列nums中的元素都是倒敘,那麽left就等於-1
if (left >= 0) {
int right = nums.size() - 1;
// 從後面尋找第一個比nums[left]大的值
while (nums[right] <= nums[left])
right--;
swap(nums[left], nums[right]);
}
// 反轉後面升序的數位
reverse(nums.begin() + left + 1, nums.end());
}
Python:
defnextPermutation(self, nums: List[int]) -> None:
left = len(nums) - 2
# 兩兩比較,從後面往前找第一個降序的
while left >= 0and nums[left] >= nums[left + 1]:
left -= 1
# 如果陣列nums中的元素都是倒敘,那麽left就等於-1
if left >= 0:
right = len(nums) - 1
# 從後面尋找第一個比nums[left]大的值
while nums[right] <= nums[left]:
right -= 1
# 交換nums[left]和nums[right]
nums[left], nums[right] = nums[right], nums[left]
# 反轉後面升序的數位
nums[left + 1:] = reversed(nums[left + 1:])