• 51 上一个排列


    原题网址:https://www.lintcode.com/problem/previous-permutation/description

    描述

    给定一个整数数组来表示排列,找出其上一个排列。

    排列中可能包含重复的整数

    您在真实的面试中是否遇到过这个题?  

    样例

    给出排列[1,3,2,3],其上一个排列是[1,2,3,3]

    给出排列[1,2,3,4],其上一个排列是[4,3,2,1]

    思路:

    首先应该清楚什么是上一个排列,可以参考全排列字典顺序  全排列的实现方法--递归&字典序 与 【C++】全排列之非递归算法——字典序法(2)

    理解了全排列字典序后,下一个排列很容易找到,那怎么找上一个排列呢?

    思路与寻找下一个排列类似,只不过过程相反。首先,从右向左开始找,找到第一个nums【i】>nums【i+1】的位置i ,即找到从右向左递减序列的前一个位置(结束递减序列的位置),该位置为第一个需要改变字符的位置t;

    注意,t+1~end 部分的元素不一定全小于nums【t】,所以需要从右向左找到第一个小于nums【t】的元素位置k,因这部分元素从右向左递减所以nums【k】为 t+1~end 部分小于nums【t】的数中最接近nums【t】的(找最接近nums【t】的是因为要找的是紧邻的上一个排列);

    交换nums【t】与nums【k】;

    将 t+1 ~ end 部分的元素翻转;(从右向左递减变为递增,保证该排列是原排列紧邻的上一个排列);

    PS:数字序列的排序与整数的排序一致,比如123<132<213<……<321,可以是排列的大小,也可以是整数的大小,有了这个认知后就很方便理解为什么求上一个排列或下一个排列要从右往左寻找变位了,因为数字的依次增大或减小总是从低位开始的,累加到一定程度才会反映到高位上。

    AC代码:

    class Solution {
    public:
        /*
         * @param nums: A list of integers
         * @return: A list of integers that's previous permuation
         */
        vector<int> previousPermuation(vector<int> &nums) {
            // write your code here
            vector<int> result=nums;
        int n=nums.size();
        int t=-1;
        for (int i=n-2;i>=0;i--)
        {
            if (result[i]>result[i+1])
            {
                t=i;
                break;
            }
        }
    
        if (t==-1)
        {
            reverse(result.begin(),result.end());
        }
        else
        {
            int k;
            for (int j=n-1;j>t;j--)
            {
                if (result[j]<result[t])
                {
                    k=j;
                    break;
                }
            }
            swap(result[t],result[k]);
            reverse(result.begin()+t+1,result.end());
        }
    
        return result;
        }
    };

    其他方法:

    https://blog.csdn.net/guoziqing506/article/details/51870732

    http://www.bubuko.com/infodetail-1310249.html 

    这个答案后面有错,【比如:40712389 右到左递减序列的前一个位置是peakInd = 2 ,3到7内左到右第一个大于7的数是8,其位置是6,交换这个两个位置的数后:40812379,下面在对3 到7位置内的数进行逆序后:40897321.就是答案了。】

    应该是【比如:40712389 右到左递减序列的前一个位置是peakInd = 2 ,9到1从右向左第一个小于7的数是3,其位置是5,交换这个两个位置的数后:40312789,下面在对1 到9位置内的数进行逆序后:40398721.就是答案了。】

    https://blog.csdn.net/sunday0904/article/details/69944640

    https://www.cnblogs.com/libaoquan/p/7087272.html

  • 相关阅读:
    java中的object类
    java中super的使用
    java中final的使用
    java中的继承初始化顺序
    java中的方法重写
    springMVC的流程
    dubbo与zookeeper
    java的几种常见数据结构
    集合框架之List和Set区别
    集合框架
  • 原文地址:https://www.cnblogs.com/Tang-tangt/p/9105987.html
Copyright © 2020-2023  润新知