31. Next Permutation

本文介绍了一种算法,用于找出一个序列的下一个字典序更大的排列。如果没有更大的排列,则将其重新排列为最小的字典序排列。文章详细解释了算法的工作原理,并提供了C++实现代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Implement next permutation, which rearranges numbers into the lexicographically next greater permutation of numbers.

If such arrangement is not possible, it must rearrange it as the lowest possible order (ie, sorted in ascending order).

The replacement must be in-place, do not allocate extra memory.

Here are some examples. Inputs are in the left-hand column and its corresponding outputs are in the right-hand column.
1,2,3 → 1,3,2
3,2,1 → 1,2,3
1,1,5 → 1,5,1

呃呃呃,其实没看懂题目,好歹我也过了六级,题目意思是找下一个大一点的全排列,输入形式我当时也没看明白,以为输入 123 , 321 , 115 三组同时输入要计算结果,最开始想着交换两个数字就可以了,后面又加了排序,不过发现自己的算法和正解就差了那么一点,但不对就是不对,看了这篇文章才知道自己错那了,点击打开链接,思想复制它的一下:

首先,关于什么是全排列不做解释。如果一个排列为A,下一个排列为A_NEXT,那么A_NEXT一定与A有尽可能长的公共前缀。

看具体例子,一个排列为124653,如何找到它的下一个排列,因为下一个排列一定与124653有尽可能长的前缀,所以,脑洞大开一下,从后面往前看这个序列,如果后面的若干个数字有下一个排列,问题就得到了解决。

第一步:找最后面1个数字的下一个全排列。

124653,显然最后1个数字3不具有下一个全排列。

第二步:找最后面2个数字的下一个全排列。

124653,显然最后2个数字53不具有下一个全排列。

第三步:找最后面3个数字的下一个全排列。

124653,显然最后3个数字653不具有下一个全排列。

------插曲:到这里相信大家已经看出来,如果一个序列是递减的,那么它不具有下一个排列

第四步:找最后面4个数字的下一个全排列。

124653,我们发现显然最后4个数字4653具有下一个全排列。因为它不是递减的,例如6453,5643这些排列都在4653的后面。

我们总结上面的操作,并总结出重复上面操作的两种终止情况:

1:从后向前比较相邻的两个元素,直到前一个元素小于后一个元素,停止

2:如果已经没有了前一个元素,则说明这个排列是递减的,所以这个排列是没有下一个排列的。

124653这个排列终止情况是上面介绍的第一种,从后向前比较相邻的2个元素,遇到4<6的情况停止。

并且我们可以知道:

1:124653和它的下一个排列的公共前缀为12(因为4653存在下一个排列,所以前面的数字12保持不变)

2:4后面的元素是递减的(上面介绍的终止条件是前一个元素小于后一个元素,这里是4<6)

现在,我们开始考虑如何找到4653的下个排列,首先明确4后面的几个数字中至少有一个大于4.

4肯定要和653这3个数字中大于4的数字中(6,5)的某一个进行交换。这里就是4要和6,5中的某一个交换,很明显要和5交换,如果找到这样的元素呢,因为我们知道4后面的元素是递减的,所以在653中从后面往前查找,找到第一个大于4的数字,这就是需要和4进行交换的数字。这里我们找到了5,交换之后得到的临时序列为5643.,交换后得到的643也是一个递减序列。

所以得到的4653的下一个临时序列为5643,但是既然前面数字变大了(4653--->5643),后面的自然要变为升序才行,变换5643得到5346.

所以124653的下一个序列为125643.

--------------------------------------最后放上自己实现的源码-----------------------------

#include <iostream> 
#include <vector> 
#include <stdlib.h>
#include <string> 
#include <algorithm>
using namespace std; 

class Solution {
public:
	void nextPermutation(vector<int>& nums) {
		int numsSize = nums.size();
		if (!numsSize) return;
		int changeIndex, pointRight;
		bool flag = false;
		int IntTemp;
		pointRight = numsSize - 1;

		while (!flag && pointRight >= 1)   //从后向前比较相邻的两个元素,直到前一个元素小于后一个元素,停止
		{
			if (nums[pointRight] > nums[pointRight - 1])
			{
				flag = true;
				break;
			}
			pointRight--;
		}
		pointRight--;

		if (flag) //如果存在下一个排列
		{
			IntTemp = INT_MAX;
			for (int i = pointRight + 1; i < numsSize; ++i)  // 查找记录节点之后比它大的里面最小的位置
			{
				if (nums[i]>nums[pointRight] && nums[i] < IntTemp)
				{
					IntTemp = nums[i];
					changeIndex = i;
				}
			}
			IntTemp = nums[changeIndex];   //交换这两个数
			nums[changeIndex] = nums[pointRight];
			nums[pointRight] = IntTemp;

			if (pointRight + 1 < numsSize - 1)
				qsort(nums, pointRight + 1, numsSize - 1);   // 将后面的变成升序
		}
		else
		{
			qsort(nums, 0, numsSize - 1); //  如果已经没有了前一个元素,则说明这个排列是递减的,所以这个排列是没有下一个排列的。所以下一个就是整个序列的升序
		}


	}
private:	void qsort(vector<int> & nums, int left, int right)   //快速排序  
	{
		if (left < right)
		{
			int i = left;
			int j = right;
			int temp = nums[left];
			while (i < j)
			{
				while (i < j && nums[j] >= temp) j--;

				if (i < j)
				{
					nums[i] = nums[j];
					i++;
				}
				while (i < j && nums[i] <= temp) i++;
				if (i < j)
				{
					nums[j] = nums[i];
					j--;
				}
			}
			nums[i] = temp;
			qsort(nums, left, i - 1);
			qsort(nums, i + 1, right);
		}

	}
};
int main()
{ 
	vector<int > haha = { 0,1,1,0,4,4 };
	Solution a;
	a.nextPermutation(haha);
	for (int i = 0; i < haha.size(); ++i)
		cout << haha[i] << ",";
	system("pause");
	return 0; 
}


在使用Keil集成开发环境进行ARM微控制器编程时,可能会遇到“找不到编译器 Missing: Compiler Version 5”的错误提示,这通常是由于Keil没有正确配置或安装了不完整的ARM Compiler v5.06导致的。本文将详细介绍如何解决这个问题。 我们需要了解ARM Compiler是什么。ARM Compiler是ARM公司开发的一套编译工具链,它包括了编译器、链接器、汇编器等组件,用于将C/C++源代码转换为适用于ARM架构处理器的目标代码。在Keil中,它用于构建和优化针对ARM芯片的应用程序。 在错误信息中提到的"arm complier v5.06",指的是ARM Compiler的版本号5.06。这个版本可能与你的Keil安装不兼容或者未被正确识别。解决这个问题的步骤如下: 1. **检查安装**:确保你已经安装了ARM Compiler v5.06。通常,这个工具会在安装Keil μVision时一起安装,但如果没有,你需要单独下载并安装。可以从ARM官网或者Keil的官方网站获取相应版本的编译器。 2. **配置Keil路径**:在Keil的安装目录下找到`TOOLS.INI`文件,这是一个配置文件,用于指定编译器的位置。确保其中的路径指向了你安装的ARM Compiler v5.06的目录。 3. **更新项目设置**:在Keil μVision中,打开你的项目,然后选择“Project” > “Options for Target” > “Toolchain”。在“Compiler”选项卡中,确认“Compiler version”已经设置为“v5.06”。如果未自动识别,可以手动输入正确的路径。 4. **环境变量**:有时,即使设置了正确的路径,Keil仍然无法找到编译器,可能是因为系统环境变量未设置好。确保`PATH`环境变量包含了ARM Compiler的bin目录,这样系统在启动Keil时才能找到编译器。 5. **重启Keil**:完成上述设置后,关闭并重新启动Keil μVision,让更改生效。如果问题仍未解决,尝试卸载并重新安装Keil和ARM Compiler。 在提供的文件列表"arm506"中,可能包含了解决这个问题所需的一些资源,如安装程序、补丁或配置文件。如果你已下载这个文件,可以按照以下步骤操作: - 解压缩文件,通常会得到一个包含编译器可执行文件的目录。 - 将这个目录路径添加到Keil的`TOOLS.INI`文件或系统环境变量`PATH`中。 - 如果是补丁文件,按照说明应用到Keil或ARM Compiler的安装目录。 通过以上步骤,大部分情况下都能解决“找不到编译器 Missing: Compiler Version 5”的问题。如果问题依然存在,可能需要检查网络连接,因为某些情况下,Keil需要访问在线许可证服务器。此外,确保你的Keil版本与ARM Compiler版本兼容,不同版本的Keil可能支持不同的ARM Compiler版本。在升级或更新任何组件时,务必查阅官方文档以获取详细信息。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值