【LeetCode】Next Permutation

133 篇文章 0 订阅
121 篇文章 2 订阅

Next Permutation 
Total Accepted: 4075 Total Submissions: 16219 My Submissions
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
这个应该是基础。在C/C++中有封装好的方法可以使用。
其实基本思路应该是这样的。
1、从尾到头寻找第一个相邻的,下降的两个数。如果是出现这种情况,说明还可以找到下一个序列。假设找到的位置是first。
2、根据1,我们可以知道,从尾到first+1,这个序列应该是上升的。从中找到第一个比num[first]大的数,然后和first交换位置。
3、从first+1到len-1进行排序,这样就完成了一次查找过程。
举个例子来说吧。

假设原始序列为[10,12,14,16,17],


查找下一个排列的过程如下:

1、从右到左找到第一个连续下降的两个数。

此时first为3。

2、从右到first+1找到第一个比它大的数,然后两个数交换。

然后对first+1之后的序列逆序,即为结果。逆序的原因是,因为每次查找的都是从右到左第一个比frist大的数,所以交换以后,first后面的序列一定是从右到左上升的。逆序以后才为最小序列。

4、下一次查找的逻辑和之前相同

5、从右到左查找第一个比first大的数,然后交换。

6、对first+1后面的序列逆序。


依次重复上述步骤,就可以得到所有的全排列。注意如果从右到左找不到下降的序列,则说明目前数据已全部有序,排序规则为从大到小,那么下一个全排列就是将当前数组逆序。

本题只要求求一个,所以一个步骤就可以了。

Java AC

public class Next_Permutation {
    public void nextPermutation(int[] num) {
        if (num == null || num.length == 0) {
            return;
        }
        int len = num.length;
        int first = getFirst(num);
        if (first == -1) {
            reverse(num, 0, len - 1);
        } else {
            int i = len - 1;
            for (; i > first; i--) {
                if (num[i] > num[first]) {
                    break;
                }
            }
            swap(num, first, i);
            reverse(num, first + 1, len - 1);
        }
    }

    public int getFirst(int[] num) {
        int len = num.length;
        for (int i = len - 2; i >= 0; i--) {
            if (num[i] < num[i + 1]) {
                return i;
            }
        }
        return -1;
    }

    public void swap(int[] num, int i, int j) {
        int tmp = num[i];
        num[i] = num[j];
        num[j] = tmp;
    }

    public void reverse(int[] num, int low, int high) {
        while (low < high) {
            swap(num, low, high);
            low++;
            high--;
        }
    }
}
Python AC

class Solution:
    # @param num, a list of integer
    # @return a list of integer
    def nextPermutation(self, num):
        nLen = len(num)
        first = -1
        for i in xrange(nLen - 2, -1, -1):
            if num[i] < num[i + 1]:
                first = i
                break
        if first == -1:
            num.sort()
            return num
        else:
            for i in xrange(nLen - 1, first, -1):
                if num[i] > num[first]:
                    num[i], num[first] = num[first], num[i]
                    break
            low = first + 1
            high = nLen - 1
            while low < high:
                num[low], num[high] = num[high], num[low]
                low += 1
                high -= 1
            return num


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值