• 46. Permutations


    一、题目

      1、审题

      2、分析:

        输入一个不重复整形数组,求他的全排序

    二、解答

      1、思路:

        方法一:利用递归实现全排序,先固定第一个值,在对后边全排序...最终当固定的值为最大下标时,则此时即得一排序。

    class Solution {
        public List<List<Integer>> permute(int[] nums) {
            Arrays.sort(nums);
            
            List<List<Integer>> resultList = new ArrayList<List<Integer>>();
            
            callAllPerm(resultList, nums, 0, nums.length - 1);
            
            return resultList;
        }
        
        // 获得全排序
        private void callAllPerm(List<List<Integer>> resultList, int[] nums, int from,
                int to) {
        
            if(from == to) {    // add
                List<Integer> list = new ArrayList<Integer>();
                for (int i = 0; i < nums.length; i++) {
                    list.add(nums[i]);
                }
                resultList.add(list);
            }
            else {
                for (int i = from; i <= to; i++) {
                    swap(nums, i, from);
                    callAllPerm(resultList, nums, from + 1, to);
                    swap(nums, i, from);
                }
            }
        }
        
        // 交换数组元素
        private void swap(int[] nums, int tempIndex, int index) {
            int temp = nums[tempIndex];
            nums[tempIndex] = nums[index];
            nums[index] = temp;
        }
    }

      

      方法二:  将数组排成升序后,依次求得比这一个数组数字大的下一个数字数组,最终这些所有的字典序的数组即为全排序。

            求字典序步骤如下,例如对于 21543而言,其下一个排序序列求法为:

            ①、从右向左找到第一个能有升序的位置i ,此时,x = ai = 1;

            ②、在 i 的右侧找到比 ai 大的最小的一个元素位置 j, 此时, y = aj = 3;(其实就是从右向左查找的第一个比 ai 大的数就是了)

            ③、交换 x 与 y

            ④、将 i + 1 到最后位置的数组元素进行翻转。

    class Solution {
        public List<List<Integer>> permute(int[] nums) {
            List<List<Integer>> resultList = new ArrayList<List<Integer>>();
            if(nums.length == 0)
                return resultList;
            
            Arrays.sort(nums);
            
            addTargetList(resultList, nums);    //加上原排序
            
            helper(resultList, nums, nums.length - 2);
            
            return resultList; 
        }
        
        /*
         *     1、交换
         *     2、翻转
         *     3、i 改变
         */
        private void helper(List<List<Integer>> resultList, int[] nums, int index) {
            
            if(index < 0)
                return;
            
            int tempIndex = -1;
            for (int i = nums.length -1; i > index; i--) {
                // 找比 index 大的最小值
                if(nums[i] > nums[index]) {
                    tempIndex = i;
                    break;
                }
            }
            
            if(tempIndex != -1) {
                swap(nums, tempIndex, index);        //交换
                reverse(nums, index+1);                // 翻转
                addTargetList(resultList, nums);    // 添加
                helper(resultList, nums, nums.length - 2);    // 重新递归
            }
            else {
                helper(resultList, nums, index - 1);    // index 向左移动
            }
        }
    
        private void addTargetList(List<List<Integer>> resultList, int[] nums) {
            List<Integer> list = new ArrayList<Integer>();
            for (int i = 0; i < nums.length; i++) {
                list.add(nums[i]);
            }
            resultList.add(list);
        }
    
        // 翻转从 index 开始的数组元素
        private void reverse(int[] nums, int index) {
            if(index < nums.length - 1) {
                for (int i = index, j= nums.length-1; j > i; i++, j--) {
                    swap(nums, i, j);
                }
            }
        }
    
        // 交换数组元素
        private void swap(int[] nums, int tempIndex, int index) {
            int temp = nums[tempIndex];
            nums[tempIndex] = nums[index];
            nums[index] = temp;
        }
    }

            

  • 相关阅读:
    7-10 社交网络图中结点的“重要性”计算(30 point(s)) 【并查集+BFS】
    7-5 打印选课学生名单(25 point(s)) 【排序】
    7-3 堆栈模拟队列(25 point(s)) 【数据结构】
    7-5 家谱处理(30 分) 【数据结构】
    7-7 最强素数(100 分) 【前缀和】
    PAT 天梯赛 L2-022. 重排链表 【数据结构】
    7-1 列出叶结点(25 分) 【数据结构】
    7-6 公路村村通(30 分) 【prime】
    PAT 甲级 1116. Come on! Let's C (20) 【循环判断】
    PAT 甲级 1104. Sum of Number Segments (20) 【数学】
  • 原文地址:https://www.cnblogs.com/skillking/p/9633194.html
Copyright © 2020-2023  润新知