• lintcode51- Previous Permutation- medium


    Given a list of integers, which denote a permutation.

    Find the previous permutation in ascending order.

    Notice

    The list may contains duplicate integers.

    Example

    For [1,3,2,3], the previous permutation is [1,2,3,3]

    For [1,2,3,4], the previous permutation is [4,3,2,1]

    函数头:public List<Integer> previousPermuation(List<Integer> nums)

    算法:和前面的类似,就是反一反,关键是明白字典序排列是怎么产生的。原则是维持尽可能多的前缀,所以要尽量换后面的排列。所以从前往后就是在最后找尽量的不能动手脚的下降序列,然后对他们动手(就是迂回通过找最后面出现的上升对来实现,因为这个上升对后面肯定就是降序了,否则这一对不会是从后往前第一个找到的)。反过来如果从后字典序往前找,就是要找落在后头的尽量长的不能动手的上升序列(如果最后下降的话你直接换一下就可以得到前一个了啊),然后对他们动手。

    本题具体步骤:

    1.从后往前找第一个出现的下降对prev-next。

    2.在next~最后中找出第一个比prev小的数字smaller。

    3.交换prev和smaller。

    4.在现在新的next~最后里排成降序(做逆序操作)

    细节:1.对List数据结构操作的话,赋值记得用list.set(idx, obj),不要remove又add,这样很麻烦。当然list.get() = xxx这种对常数赋值的操作是肯定错误的。2.for(int i = 0, j = nums.length -1; ...; ),这里面同时创造ij并赋值,记得写一个int就好了,同行写两个不可能用逗号隔开啊,所以肯定不行的,基础语法。

    public class Solution {
        /*
         * @param nums: A list of integers
         * @return: A list of integers that's previous permuation
         */
        public List<Integer> previousPermuation(List<Integer> nums) {
    
            //这里实现类型有讲究吗
            List<Integer> result = new ArrayList<Integer>(nums);
            
            int prev = 0;
            int next = 0;
            for (int i = nums.size() - 2; i >= 0; i--) {
                if (nums.get(i) > nums.get(i + 1)) {
                    prev = i;
                    next = i + 1;
                    break;
                }
            }
            
            if (prev == next) {
                reverse(result, 0, result.size() - 1);
                return result;
            }
            
            int smaller = next;
            for (int i = nums.size() - 1; i > next; i--) {
                if (nums.get(i) < nums.get(prev)) {
                    smaller = i;
                    break;
                }
            }
            
            swap(result, prev, smaller);
            reverse(result, next, result.size() - 1);
            
            return result;
        }
        
        
        // 想看swap怎么写的,用set写的吗
        private void swap(List<Integer> nums, int idx1, int idx2) {
            int temp = nums.get(idx1);
            nums.set(idx1, nums.get(idx2));
            nums.set(idx2, temp);
        }
        
        private void reverse(List<Integer> nums, int start, int end) {
            for (int i = start, j = end; i < j; i++, j--) {
                swap(nums, i, j);
            }
        }
    }
  • 相关阅读:
    python多线程学习一
    https学习笔记三----OpenSSL生成root CA及签发证书
    https学习笔记二----基础密码学知识和python pycrypto库的介绍使用
    HTTPS学习笔记一----HTTPS的基础理论知识
    一只小鹅的2017
    python 全局变量的import机制
    一起来学设计模式-----工厂模式的实践
    一起来学设计模式-----创建型模式之抽象工厂
    一起来学设计模式-----创建型模式之工厂方法
    一起来学设计模式-----创建型模式之简单工厂
  • 原文地址:https://www.cnblogs.com/jasminemzy/p/7782140.html
Copyright © 2020-2023  润新知