leetcode数组专项习题:下一个排列

版权声明:本文为博主原创,未经允许请不要转载哦 https://blog.csdn.net/weixin_43277507/article/details/88135798

9、下一个排列
题设要求:实现获取下一个排列的函数,算法需要将给定数字序列重新排列成字典序中下一个更大的排列。
如果不存在下一个更大的排列,则将数字重新排列成最小的排列(即升序排列)
必须原地修改,只允许使用额外常数空间。
思路:理解题意,寻找手动算法的原理
(1)从数组最后一个元素开始扫描,寻找到nums[i] > nums[i - 1]的第一个i值。
(2)如果得到i值大于等于1,说明数组存在下一个排列。
a.我们还是从数组最后一个元素开始扫描,寻找到num[j] > nums[i - 1]的第一个j值。由于nums[i] > nums[i - 1],所以我们的j值一定是大于等于i的。
b.交换索引为i - 1和索引为j的元素的值。
c.此时索引i及之后的排列时一个降序排列,将其变成升序排列即可。
为什么说此时索引i及之后的排列是一个降序排列呢?
对于原来的数组,由于我们是从数组最后一个元素开始扫描寻找到的nums[i] > nums[i - 1]的第一个i值,我们原数组中i之后的排列一定是一个降序排列。那么我们只需要看交换之后是否依然是一个降序排列呢?
而寻找索引j,我们还是从数组最后一个元素开始扫描,寻找到num[j] > nums[i - 1]的第一个j值。对于索引j之后的值,一定是小于等于nums[i - 1]的。对于而对于索引i到j - 1这部分元素,一定是大于等于num[j]的,自然一定大于nums[i - 1],那么,交换之后,原数组中i之后的排列一定依然是一个降序排列。
(3)如果得到的i值小于1,说明数组不存在下一个排列,倒序输出数组即得升序排列
分析:
代码如下:

public class Solution{
    public static void main(String[] args) 
    {
    	Solution sl = new Solution();
    	int[] nums= {1,4,3,2};
    	int len=nums.length;
    	sl.nextPermutation(nums);
        for(int i=0;i<len;i++)
        {
        	System.out.print(nums[i]);
        }
    }
    public void nextPermutation(int[] nums) {
		int n = nums.length;
		int i = n - 1;
		for(; i >= 1; i--) {
			if(nums[i] > nums[i - 1]) {
				break;
			}
		}
		if(i >= 1) {
			int j = n - 1;
			for(; j >= i; j--) {
				if(nums[j] > nums[i - 1]) {
					break;
				}
			}
			swap(i - 1, j, nums);
			reverse(nums, i);
		}else {
			reverse(nums, 0);
		}
	}
	
	private void reverse(int[] nums, int index) {
		int i = index;
		int j = nums.length - 1;
		while(i < j) {
			swap(i, j, nums);
			i++;
			j--;
		}
	}
 
	private void swap(int i, int j, int[] nums) {
		int temp = nums[i];
		nums[i] = nums[j];
		nums[j] = temp;
	}

}

猜你喜欢

转载自blog.csdn.net/weixin_43277507/article/details/88135798