【算法百题之六十】下一个排列

                 【算法百题之六十】下一个排列

 

   大家好,我是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;
		}
	}
}

因为对时间复杂度没有要求,所以我们实现升序直接冒泡排序即可。

测试结果:

 

OK,今天的博客就到这里,谢谢大家!!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Lampard杰

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值