• lintcode:previous permutation上一个排列


    题目

    上一个排列

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

    样例

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

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

    注意

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

    解题

     排列的特征

    123 的排列依次是:123、132、213、231、312、321

    要点:

    1.整体来说是升序的

    2.对一个数而言,各位数字中,大的数字越靠后,这个数在排列的位置越靠前,同样,小的数字越靠前,这个数在排列的位置越靠前

    参考1 参考2 上面说的方法好像都是一样的

    1.对每位数字,先找到从右到左递减序列前一个位置

    2.当这个位置是-1的时候,原数字逆序就是答案,比如是12345,右到左递减序列的前一个位置是 -1  ,原数字直接逆序:54321 就是答案,注意这里的排列要是和循环的,不然第一个数没有前一个数了

    3.当这个位置不是-1  说明原数字不是排列中的第一个数

    设这个位置是peakInd,这个位置的数是nums[peakInd] 。我们知道nums[peakInd] > nums[peakInd +1]     但是不是nums中从 peakInd 到nums.size() -1 内的数都一定小于nums[peakInd],我们找到第一个nums[swapInd] > nums[peakInd] 并将这两个数进行交换

    4.交换之后从peakInd + 1 到nums.size() -1 这里的数也一定是非递减的,对这部分的数逆序后,整体的数就是答案了。

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

    这里的第一点就是,先找到右到左的递减序列,这个递减序列“逆序”后,左到右就是递增的序列,上面递减序列数字组成的最大的数。

    同时要对找到的递减序列前一个数,和该递减序列的第一个大于它的数进行交换,至于为什么,我不是很理解,最后逆序就是上一行刚说的了。

    Java

    public class Solution {
        /**
         * @param nums: A list of integers
         * @return: A list of integers that's previous permuation
         */
        public ArrayList<Integer> previousPermuation(ArrayList<Integer> nums) {
            // write your code
            int peakInd = nums.size() - 1;
            // 从后向前走,找到第一个nums[peakInd - 1] > nums[peakInd] 退出
            // 后向前走 降序序列的最后一个位置跳出
            while(peakInd > 0 && nums.get(peakInd - 1) <= nums.get(peakInd)){
                peakInd--;
            }
            //降序序列的前一个位置 
            peakInd--;
            if(peakInd >= 0){
                int swapInd = peakInd + 1;
                while(swapInd< nums.size() 
                    && nums.get(swapInd) < nums.get(peakInd)){
                    swapInd++;
                }
                swapInd--;
                int tmp = nums.get(swapInd);
                nums.set(swapInd,nums.get(peakInd));
                nums.set(peakInd,tmp);
            }
            int left = peakInd + 1;
            int right = nums.size() - 1;
            while(left < right){
                int tmp = nums.get(left);
                nums.set(left,nums.get(right));
                nums.set(right,tmp);
                left ++;
                right --;
            }
            return nums;
        }
    }
    Java Code

     凭借刚做的印象有写了一遍

    public class Solution {
        /**
         * @param nums: A list of integers
         * @return: A list of integers that's previous permuation
         */
        public ArrayList<Integer> previousPermuation(ArrayList<Integer> nums) {
            // write your code
            int peakInd = nums.size() - 1;
            while(peakInd >0 && nums.get(peakInd)>=nums.get(peakInd-1)){
                peakInd --;
            }
            peakInd --;
            if(peakInd >=0){
                int swapInd = peakInd + 1;
                while(swapInd < nums.size() && nums.get(peakInd) >nums.get(swapInd)){
                    swapInd +=1;
                }
                swapInd--;
                int tmp = nums.get(swapInd);
                nums.set(swapInd,nums.get(peakInd));
                nums.set(peakInd,tmp);
            }
            int left = peakInd + 1;
            int right = nums.size() - 1;
            while(left < right){
                int tmp = nums.get(left);
                nums.set(left,nums.get(right));
                nums.set(right,tmp);
                left++;
                right--;
            }
            return nums;
        }
    }
    Java Code

     Python

    class Solution:
        # @param num :  a list of integer
        # @return : a list of integer
        def previousPermuation(self, nums):
            # write your code here
            peakInd = len(nums) - 1
            
            while peakInd>0 and nums[peakInd] >= nums[peakInd - 1]:
                peakInd -=1
            peakInd -=1
            if peakInd >=0:
                swapInd = peakInd + 1
                while swapInd< len(nums) and nums[peakInd] > nums[swapInd]:
                    swapInd +=1
                swapInd -=1
                nums[swapInd],nums[peakInd] =nums[peakInd] ,nums[swapInd]
            left = peakInd + 1
            right = len(nums) - 1
            while left< right:
                nums[left],nums[right] = nums[right],nums[left]
                left +=1
                right -=1
            return nums
            
    Python Code

      

  • 相关阅读:
    VR全景项目外包团队— VR/AR相关领域介绍和VR全景案例
    虚拟现实外包公司— VR开发编辑器意义重大 印证VR不仅服务于用户
    全景VR视频游戏外包公司:技术分享使用U3D+CB制作VR游戏
    承接Unity3D外包公司 — 技术分享
    承接cardboard外包,unity3d外包(北京动软— 谷歌CARDBOARD真强大)
    VR外包团队:长年承接VR虚拟现实外包(应用、游戏、视频、漫游等)
    北京全景视频外包公司:长年承接VR全景视频外包
    北京VR视频外包团队:全景VR视频科普
    全景VR视频外包公司:长年承接VR全景视频外包(技术分享YouTube的360全景视频)
    Unity3D外包团队——技术分享U3D全景漫游(三)
  • 原文地址:https://www.cnblogs.com/theskulls/p/5116383.html
Copyright © 2020-2023  润新知