• LeetCode31题,下一个排列


    题目内容:

    题目解析:也就是说,用一个数组来表示一个数,数组最右边是个位。找到大于这个数的另一个数b,这个数b不仅要大于给出的数,还要尽可能小。

    方法:

    1.题目是找出大于当前数的最小的那个数。假如从左到右,数字按降序走,则一定不可能有更大的数。因为从左到右降序的话,数字一定是最大的。
    2.所以说,应该从右往左找,第一个满足(左到右升序)nums[i-1]<nums[i]的下标i-1,令mark=i-1。此时nums[mark]<nums[mark+1],nums[mark+1]到数组结尾是降序。
    3.mark右侧(不包括mark)应该是一个从左到右的递减序列,在这个序列里,找大于nums[mark]的最小的数的下标mark1。交换nums[mark]和nums[mark1]。
    4.交换之后,因为mark处的数字已经比原来的大了,[0,mark]处的数字不变,所以当前数一定大于原来的数,但是不一定是最小的那个,怎样找到最小的那个数呢?把mark右侧,不包括mark的所有的数变成从左到右的升序即可。

    class Solution {//看笔记
        public void nextPermutation(int[] nums) {
            if(nums.length==2&&nums[0]>nums[1])
            {
                swap(nums,0,1);
                return ;
            }
            else if(nums.length==2&&nums[0]<=nums[1])
            {
                swap(nums,0,1);
                return;
            }
            int length=nums.length;
            int mark=-1;
            int mark1=-1;//大于nums[mark]的第一个数
            int i=length-1;
            int j=nums.length-1;
            for(;i>0;i--)//从右到左找nums[i-1]<nums[i]的数i-1
            {
                if(nums[i-1]>=nums[i]) continue;//这里会错,要找递增的数,递增的反面就是>=
                else
                {
                    break;
                }
            }
            int biaoji=i;//用一个数标记i
            if(biaoji>0)//假如biaoji==0,说明从左到右所有数字依次递减,无更大的数,直接反转所有数字即可
            {
                mark=biaoji-1;//要找的那个数,mark右侧的数组是递减的,但是nums[mark]<nums[mark+1]
                for(;j>mark;j--)//找大于nums[mark]的最小的数
                {
                    if(nums[j]>nums[mark])//mark是下标,不是数字,这里别写错
                    {
                        break;
                    }
                }
                mark1=j;
                swap(nums,mark,mark1);
                 reverse(nums,mark+1);
                
            }
           if(biaoji==0)//此时,从左到右,序列递减,没有更大的数,按照题意,整个数组变成升序即可
            {
                reverse(nums,0);
            }
           
           
    
        }
    
        public void swap(int[] nums,int a,int b)//交换两个数
        {
            int temp=nums[a];
            nums[a]=nums[b];
            nums[b]=temp;
        }
        private void reverse(int[] nums, int start) {//如果对一个降序数组用这个函数,从start开始,包括start,变成升序
            int i = start, j = nums.length - 1;
            while (i < j) {
                swap(nums, i, j);
                i++;
                j--;
            }
        }
    
    
    }
    

      结束。

  • 相关阅读:
    005 Python的IDE之Pycharm的使用
    006 Python的IDE之Jupyter的使用
    004 pip的使用
    003 Python解释器源修改
    002 Python解释器安装
    BZOJ 4567 [SCOI2016]背单词 (Trie树、贪心)
    BZOJ 2085 luogu P3502 [POI2010]Hamsters (KMP、Floyd、倍增)
    UOJ #219 BZOJ 4650 luogu P1117 [NOI2016]优秀的拆分 (后缀数组、ST表)
    UOJ #214 [UNR #1]合唱队形 (概率期望计数、DP、Min-Max容斥)
    LOJ #2542 [PKUWC2018]随机游走 (概率期望、组合数学、子集和变换、Min-Max容斥)
  • 原文地址:https://www.cnblogs.com/lzh1043060917/p/12736589.html
Copyright © 2020-2023  润新知