LeetCode 31 Next Permutation 解题记录

本文解析LeetCode第31题“下一个排列”的解题思路及Java实现。通过寻找递减子序列边界并交换元素,实现输入序列的下一个字典序排列。

刚入职不久,打算分门别类的刷一下LeetCode,于是首先从Array类的题目开始。今天做到一个题目,题号是31,原文题目如下:

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

刚开始连题目也没读懂,后来百度了一下,得知题目大意是:


写一个方法,实现输入排列的增大,即把输入排列增大到按字典序的下一个排列,若输入排列已经是最后一个排列,则将其升序排序。此外,题目要求不能分配额


外的空间,并给出了几个示例。


题中的permutation指的就是数学中的排列,举个栗子:

数字1,2,3的全排列依次是

1 2 3

1 3 2

2 1 3

2 3 1

3 1 2

3 2 1

结合题意,个人的理解是,“下一个排列”指的是在输入序列的全排列中,当前输入排列的下一个排列,也可将每一个排列看成一个数字,如1 2 3看成123,那么它的


下一个排列1 3 2就是132,132>123。


题目虽然弄懂了,但是想了一会也没有什么好的思路,看到nomasp博客上的思路,觉得很棒,于是想记录下来。


解题思路分析如下:


假设输入排列为 6 5 4 8 7 5 1


那么如何得到这个排列的下一个更大的排列呢,我们可以从排列的尾部开始看,如果交换1和5,得到的新排列是变小的,同样,任意交换7 5 1三个数字也不可能得


到比原排列更大的排列,更进一步,8 7 5 1的任意一个新排列也不会使原排列增大,那么我们可以发现,输入排列中的递减子排列对排列的增大是无用的。因此,如果


要使输入排列增大,我们必须找到增大的那个位置,即与输入排列从尾部开始扫描得到的递减子排列相邻的那个位置。这个位置就是与 8 7 5 1相邻的4,另外在8 7 5 1


四个数中比4大的数是5 7 8,因此4需要与5交换位置,即与比4大的所有数中的最小者交换位置,交换后得到:6 5 5 8 7 4 1,然后再对8 7 4 1做一个递增排序,就得到


了题目要求的排列。


Java实现的代码如下:

public static int[] nextPermutation(int[] nums) 
{
        int n = nums.length;
        if(nums ==null || n == 1)
        	return nums;
        int index = n-1;
        while(index >0&&nums[index] <= nums[index-1])
        {
        	--index;
        }
        if(index == 0)
        {
        	Arrays.sort(nums);
        	return nums;
        }
        int big = Integer.MAX_VALUE;
        int bigindex = 0;
        for(int i = n-1;i >= index-1;--i)
        {
        	if(nums[i] > nums[index-1])
        	{
        		if(nums[i] < big)
        		{
        			big = nums[i];
        			bigindex = i;
        		}
        	}
        }
        int temp;
        temp = nums[index-1];
        nums[index-1] = nums[bigindex];
        nums[bigindex] = temp;

        Arrays.sort(nums, index, n);//排序时包括index,不包括n
        return nums;
   }





一、基础信息 数据集名称:Bottle Fin实例分割数据集 图片数量: 训练集:4418张图片 验证集:1104张图片 总计:5522张图片 分类类别: - 类别0: 数字0 - 类别1: 数字1 - 类别2: 数字2 - 类别3: 数字3 - 类别4: 数字4 - 类别5: 数字5 - 类别6: Bottle Fin 标注格式:YOLO格式,包含多边形坐标,适用于实例分割任务。 数据格式:图片格式常见如JPEG或PNG,具体未指定。 二、适用场景 实例分割AI模型开发:数据集支持实例分割任务,帮助构建能够精确识别和分割图像中多个对象的AI模型,适用于对象检测和分割应用。 工业自动化与质量控制:可能应用于制造、物流或零售领域,用于自动化检测和分类物体,提升生产效率。 计算机视觉研究:支持实例分割算法的学术研究,促进目标检测和分割技术的创新。 教育与实践培训:可用于高校或培训机构的计算机视觉课程,作为实例分割任务的实践资源,帮助学生理解多类别分割。 三、数据集优势 多类别设计:包含7个不同类别,涵盖数字和Bottle Fin对象,增强模型对多样对象的识别和分割能力。 高质量标注:标注采用YOLO格式的多边形坐标,确保分割边界的精确性,提升模型训练效果。 数据规模适中:拥有超过5500张图片,提供充足的样本用于模型训练和验证,支持稳健的AI开发。 即插即用兼容性:标注格式直接兼容主流深度学习框架(如YOLO),便于快速集成到各种实例分割项目中。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值