【算法百题之六十】下一个排列
大家好,我是Lampard~~
很高兴又能和大家见面了,接下来准备系列更新的是算法题,一日一练,早日升仙!
今天的问题是:下一个排列
示例:
输入:nums = [1,2,3] 输出:[1,3,2]
输入:nums = [3,2,1] 输出:[1,2,3]
输入:nums = [1,1,5] 输出:[1,5,1]
题解:
题目的意思是若当前三个数组合起来,并不是最大的数,则输出仅比其大的数,若组合起来已经是最大的数则输出最小的数。如1,2,3我们理解成123,那么仅比其大就是132,3,2,1已经是最大的组合,那么就输出最小的数123。
思路:
那么思路就很明确了,首先要排除特殊情况,本身已经是最大的数。那么怎么排除呢,就是从高位到低位,数字的大小都是递减的那么就是本身是最大的数。
比如987654,本身就最大了
那如果存在有其中一位,低位比高位数大,就不是最大的数
比如987564,那么6比5大,就不是最大的数
所以我们就可以这样去判断。
bool isBiggest = true;
for (int i = 0; i < nums.size() - 1; i++) {
if (nums[i] < nums[i + 1]) {
isBiggest = false;
break;
}
}
若本身是最大的我们就把它们头尾交换一下位置即可
int tmp;
if (isBiggest == true) {
for (int i = 0; i < nums.size() / 2; i++) {
tmp = nums[i];
nums[i] = nums[nums.size() - i - 1];
nums[nums.size() - i - 1] = tmp;
}
return;
}
若本身不是最大的,就要开始找到仅比当前数大的数。注意这个仅,就是说1234我们只能输出1243,而不能其他更大的数。我们知道对于数字来说,在前面的是高位,后面的是低位。所以要找到仅比当前数大的数,我们要从后往前遍历。
for(int i = nums.size(); i >= 0; i++){}
从后往前找,比后面任意一個數小(i),交换位置,然后把i到nums.size()的值进行排序,就像如果1 3 4 2,因为4比3大所以直接4和3交换位置,然后变成1 4 3 2,之后把3 2升序,变成1423
算法代码:
// 对index位置之后的元素从小到大进行排序
void sortVec(vector<int> &vec, int index) {
int tmp;
for (int i = index; i < vec.size() - 1; i++) {
for (int j = index; j < vec.size() - (i - index + 1); j++) {
if (vec[j] > vec[j + 1]) {
tmp = vec[j];
vec[j] = vec[j + 1];
vec[j + 1] = tmp;
}
}
}
}
// 拿到比起当前位置元素要大的最小位置
int getIndex(int curIndex, vector<int> &vec) {
int index = -1;
for (int i = vec.size() - 1; i > curIndex; i--) {
if (vec[i] > vec[curIndex]) {
if (index == -1)
index = i;
else
index = vec[index] > vec[i] ? i : index;
}
}
return index;
}
void nextPermutation(vector<int>& nums) {
bool isBiggest = true;
for (int i = 0; i < nums.size() - 1; i++) {
if (nums[i] < nums[i + 1]) {
isBiggest = false;
break;
}
}
int tmp;
if (isBiggest == true) {
for (int i = 0; i < nums.size() / 2; i++) {
tmp = nums[i];
nums[i] = nums[nums.size() - i - 1];
nums[nums.size() - i - 1] = tmp;
}
return;
}
int index;
// 思路,从后往前找,比后面任意一個數小(i),交换位置,然后把i到nums.size()的值进行排序
for (int i = nums.size() - 1; i >= 0; i--) {
index = getIndex(i, nums);
if (index != -1) {
tmp = nums[i];
nums[i] = nums[index];
nums[index] = tmp;
sortVec(nums, i + 1);
return;
}
}
}
因为对时间复杂度没有要求,所以我们实现升序直接冒泡排序即可。
测试结果: