码迷,mamicode.com
首页 > 编程语言 > 详细

leetcode Add to List 31. Next Permutation找到数组在它的全排列中的下一个

时间:2017-06-29 01:02:30      阅读:163      评论:0      收藏:0      [点我收藏+]

标签:public   ext   遍历   循环   span   div   答案   blog   应该   

直接上代码

public class Solution {
    /*
    做法是倒着遍历数组,目标是找到一个数比它前边的数大(即这个数后边的是降序排列),如果找到了那么这个数前边的那个数就是需要改变的最高位,如果找不到说明数组是倒序排列的,按照要求应该将数组倒过来。找到主要改变的最高位后要找谁和他交换,由于它前边的数不能变,所以那个数要倒着遍历[它+1,末尾]这个区间里的数,由于这个区间肯定是降序的,所以倒着找到的第一个就是应该交换的,交换之后的区间还是降序。这两步做完之后还要做一个工作,将这个区间的数变成升序(因为升序排列是最小的),由于本身就是降序,所以反转数组就行。
    */
    public void nextPermutation(int[] nums) {
        int l = nums.length;
        if(l < 2)
        return;
        int point = -1;
        //找到需要改变的最高位,找到别忘记break
        for(int i=l-1;i>0;i--)
        {
            if(nums[i] > nums[i-1])
            {
                point = i-1;
                //记得跳出循环
                break;
            }
        }
        //找不到的话直接反转数组
        if(point == -1)
        {
            for(int i = 0;i < l/2;i++)
            {
                swmp(nums,i,l-i-1);
            }
            return;
        }
        //全排列的下一个是和当前排列差最最小的排列,所以接下来的工作就是找寻,怎么交换才能做到比现在的数组大,还要是所有可能答案中最小的
        //找到那个和最高位交换的数,就是后边区间中比最高位的数要大的最小的数,用符合条件的最小的数交换才能最小
        for(int i =l-1;i>point;i--)
        {
            if(nums[i] > nums[point])
            {
                swmp(nums,point,i);
                break;
            }
        }
        //最后反转区间,升序保证最小
        
        int end = (l+point+1)/2;
        for(int i = point+1;i<end;i++)
        {
            swmp(nums,i,l-(i-point));
        }
        
    }
    public void swmp(int[] nums,int i,int j)
        {
            int temp = nums[i];
            nums[i] = nums[j];
            nums[j] = temp;
        }
}

 

leetcode Add to List 31. Next Permutation找到数组在它的全排列中的下一个

标签:public   ext   遍历   循环   span   div   答案   blog   应该   

原文地址:http://www.cnblogs.com/stAr-1/p/7091985.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!