• 全排列问题Ⅰ(Java实现)


    给定一个没有重复数字的序列,返回其所有可能的全排列。

    示例:

    输入: [1,2,3]
    输出:
    [
      [1,2,3],
      [1,3,2],
      [2,1,3],
      [2,3,1],
      [3,1,2],
      [3,2,1]
    ]
    看到这个题目,我们应该有这样的思路:
    比如就如题【1,2,3】,我们来分析:
      1.定1,来求2,3的全排列
        1.1.定2,来求3的全排列
          1.1.1.只有3了。所以得到的答案为【1,2,3】
        1.2回到刚刚的2,3全排列,因为3排了,2没有变,所以此时2不得不变,得到的答案是【1,3,2】
      2.定1已经完了,这时候1不得不变了,所以定2,求1,3的全排列
        2.1.定1,来求3的全排列
          2.1.1.只有3了。所以得到的答案为【2,1,3】
        2.2回到刚刚的1,3全排列,因为3排了,1没有变,所以此时1不得不变,得到的答案是【2,3,1】
      2.定1,2已经完了,这时候1,2不得不变了,所以定3,求1,2的全排列
        2.1.定1,来求2的全排列
          2.1.1.只有2了。所以得到的答案为【3,1,2】
        2.2回到刚刚的1,2全排列,因为2排了,1没有变,所以此时1不得不变,得到的答案是【3,1,2】
    因此最后的答案是【1,2,3】 【1,3,2】 【2,1,3】 【2,3,1】 【3,1,2】 【3,1,2】
    我们可以再来一个复杂的例子:

    比如:[1,2,4,5]我们要求它的全排列,分析如下:
      1.定1,来求2,4,5的全排列
        1.1.定2,来求4,5的全排列
          1.1.1.定4,求5的全排列,
            1.1.1.1只有5了。所以得出【1,2,4,5】
          1.1.2回到刚才的保持2不变,求4,5的排列。因为4不变过,所以4不能打头了。故结果为【1,2,5,4】
        1.2.等到2以后的都排列完了后,2不得不变,所以定4,求2,5的全排列
          1.2.1.保持2不变,求5的全排列
            1.2.1.1.只有4了。所以得出【1,4,2,5】

          1.2.2回到刚才的保持4不变,求2,5的排列。因为2不变过,所以2不能打头了。故结果为【1,4,5,2】
        1.3.等到2.4都定完了后,2,4不得不变,所以定5,求2,4的全排列
          1.2.1.保持2不变,求4的全排列
            1.2.1.1.只有4了。所以得出【1,5,2,4】
          1.2.2回到刚才的保持5不变,求2,4的排列。因为4不变过,所以4不能打了。故结果为【1,5,4,2】
                  ..............
     所以以第一个打头的有 【1,2,4,5】  【1,2,5,4】  【1,4,2,5】 【1,4,5,2】 【1,5,2,4】 【1,5,4,2】
    这只是定第一个数字的情况,其他的和这个类似,就不多写重复的思路了。
              ...........
    具体的实现代码如下:
    package edu.ymm.about_permutation;
    
    import java.util.ArrayList;
    import java.util.List;
    
    public class Permutation {
    	static List<List<Integer>> lists=new ArrayList<>();
        public static List<List<Integer>> permute(int[] nums) {
     
            List<Integer> list=new ArrayList<>();
            if(nums.length==0||nums==null){
                return lists;
            }
            permute(nums,list,0);
            return lists;
        }
     
        private static void permute(int[] nums,  List<Integer> list, int index) {
            //边界值判断
        	if(index==nums.length){
                lists.add(new ArrayList<>(list));
                return;
            }
            //i是从开始 i=index ;swap(,i)index相当于固定当前位置,在进行下一位的排列。
            for(int i=index;i<nums.length;i++){
                swap(nums,index,i);   //第一次交换定点之后的
                list.add(nums[index]); //把找到的加进去
                permute(nums,list,index+1); //进行递归
                list.remove(list.size()-1); //其中定位定完的需要定后面的数据
                swap(nums,index,i); //这是交换定点的,也就是重新返回上一级进行交换
     
            }
     
        }
     
        private static void swap(int[] nums, int index, int i) {
    		int t =nums[index];
    		nums[index] = nums[i];
    		nums[i] = t;
    	}
    
    	public static void main(String[] args){
            int[] nums=new int[]{1,2,3};
            List<List<Integer>> lists=new ArrayList<>();
            lists=permute(nums);
            for(List<Integer> list:lists){
                for(int i:list){
                    System.out.print(i+" ");
                }
                System.out.println();
            }
        }
    }
    
    
    

     执行结果为:

     
  • 相关阅读:
    iOS-实现键盘右上角完成按钮
    iOS-开发中单例模式的实现
    iOS-实现高斯模糊效果(swift)
    iOS-解决UITableView有footerView时最后一个cell不显示分割线问题
    fenics 笔记 -- Possion Problem
    笔记
    Hyper-reduced projective dynamics 手推公式
    Gmsh 四面体单元剖分
    SoftRoboSim 之程序框架
    物理引擎中的时间积分方法及求解
  • 原文地址:https://www.cnblogs.com/youdiaodaxue16/p/10737748.html
Copyright © 2020-2023  润新知