leetcode算法【31】下一个排列

所有题目源代码:Git地址

题目

实现获取下一个排列的函数,算法需要将给定数字序列重新排列成字典序中下一个更大的排列。

如果不存在下一个更大的排列,则将数字重新排列成最小的排列(即升序排列)。

必须原地修改,只允许使用额外常数空间。

以下是一些例子,输入位于左侧列,其相应输出位于右侧列。
1,2,31,3,2
3,2,11,2,3
1,1,51,5,1

方案

  • 这题有点费解,其实说白了就是数组看成一个数,找出这么多数拼出的刚好比原来的大的数,如果没有,那么直接找拼出来最小的数
  • 如此依赖,方案就是,从又往前找,找到一个index ,满足nums[index-1]<nums[index],则以index为点,找[index,length-1]的比nums[index-1]大的最少的那个数,填到index-1的位置,其余的地方([index,length-1])升序排列。
class Solution {
        public void nextPermutation(int[] nums) {
            //降序遍历,找到第一个后者>前者的位置x,以此为轴,找到后方<=x且>x-1的值,交换即可,x后边应当变为升序
            int len = nums.length;
            int j;
            boolean jud = false;
            if (len <= 1) return;
            if (len == 2) {
                change(nums, 0, 1);
                return;
            }
            for (int i = len - 1; i >= 0; i--) {
                if (nums[i] > nums[i - 1]) {
                    //[i,len-1]中找出一个比i-1大的最少的数
                    if (i == len - 1) {
                        change(nums, i - 1, i);
                        return;
                    }
                    j = i + 1;
                    for (; j < len; j++) {
                        if (nums[j] <= nums[i - 1]) {
                            //找到,交换
                            change(nums, i - 1, j - 1);
                            //然后排序,接着break
                            Arrays.sort(nums, i, len);
                            return;
                        }
                    }
                    change(nums, i - 1, len - 1);
                    Arrays.sort(nums, i, len);
                    return;
                }
            }
            Arrays.sort(nums);
        }

        public void change(int[] nums, int i, int j) {
            int temp = nums[i];
            nums[i] = nums[j];
            nums[j] = temp;
        }
    }
复杂度计算
  • 时间复杂度:由于有快排的存在,O(logn),实际上应当是不到这个级别的
  • 空间复杂度:O(1)

杂记Arrays.sort()

原创文章 179 获赞 270 访问量 34万+

猜你喜欢

转载自blog.csdn.net/symuamua/article/details/105960096