《算法笔记》第3章 入门篇(1)——入门模拟

153 阅读1分钟

4.1 排序

很多排序题都会要求在排序之后计算出每个个体的排名,并且规则一般是:分数不同的排名不同,分数相同的排名相同但是占用一个排位。例如有五学生的分数分别为90、88、88、88、86,那么这五个学生的排名分别为1、2、2、2、5.

对这种要求,一般都需要在结构体类型定义时就把排名这一项加到结构体中。于是在数组排序完成后就有下面的方法来实现排名的计算:

stus.get(0).finalRank=1;
for(int i=1;i< stus.size();i++){
    if(stus.get(i).score==stus.get(i-1).score){
        stus.get(i).finalRank=stus.get(i-1).finalRank;
    }else{
        stus.get(i).finalRank=i+1;
    }
}

4.3 递归

  1. 全排列问题

    就像一个按顺序填空问题

public class QuanPaiLie {

    final static int maxn=11;

    static int n;//1~n的全排列
    static int[] P=new int[maxn];//当前排列
    static boolean[] hashTable=new boolean[maxn];//记录整数x是否已经在P中

    //当前处理排列的第index号位
    public static void generateP(int index){
        if(index==n+1){//递归边界
            for(int i=1;i<=n;i++){
                System.out.print(P[i]+" ");
            }
            System.out.println();
        }

        for(int x=1;x<=n;x++){
            if(hashTable[x]==false){
                P[index]=x;
                hashTable[x]=true;
                generateP(index+1);
                hashTable[x]=false; //递归回来以后需要还原状态
            }
        }
    }

    public static void main(String[] args) {
        n=5;
        generateP(1);
    }

}
  1. n皇后问题(不回溯)

    本质上就是个全排列问题

public class Nhuanghou {

   final static int maxn=20;

   static int cnt=0;//cnt种情况
   static int N;//1~N个皇后
   static int[] P=new int[maxn];//P[i]=j表示:第i列填入的皇后在第j行
   static boolean[] isInP=new boolean[maxn];//isInP[i]=true:表示第i行已经有皇后

   public static void generateP(int index){
       if(index==N+1){//递归边界,此时N个皇后已经填满,全排列机制保证了这N个皇后不在同一行、列,但无法保证不在同一对角线,需要进行判断
           boolean flag=true;
           for(int i=1;i<=N;i++){//遍历任意两个皇后
               for(int j=i+1;j<=N;j++){
                   if(Math.abs(i-j)==Math.abs(P[i]-P[j])){//如果在一条对角线上,行差的绝对值==列差的绝对值
                       flag=false;
                   }
               }
           }
           if(flag){
               cnt++;
           }
           return;
       }
       for(int i=1;i<=N;i++){
           if(isInP[i]==false){
               P[index]=i;//这里index对应行,x对应列----->全排列问题中:index相当于数组下标,x相对于填进去的值
               isInP[i]=true;
               generateP(index+1);
               isInP[i]=false;
           }
       }
   }

   public static void main(String[] args) {
       N=8;
       generateP(1);
       System.out.println(cnt);
   }
}
  1. n皇后问题(回溯)
public class Nhuanghou2 {

    final static int maxn=20;

    static int cnt=0;//cnt种情况
    static int N;//1~N个皇后
    static int[] P=new int[maxn];//P[i]=j表示:第i列填入的皇后在第j行
    static boolean[] isInP=new boolean[maxn];//isInP[i]=true:表示第i行已经有皇后

    public static void generateP(int index){
        if(index==N+1){//能到达递归边界则一定满足条件,因为采用了回溯法
            cnt++;
            return;
        }
        for(int i=1;i<=N;i++){//第i行
            if(isInP[i]==false){//第i行还没有皇后
               boolean flag=true;//flag为true表示当前皇后不会和之前的皇后冲突,当前皇后准备放在第index列第i行
               for(int pre=1;pre<index;pre++){//遍历之前的皇后
                   if(Math.abs(index-pre)==Math.abs(i-P[pre])){
                       flag=false;
                       break;
                   }
               }
               if(flag){//判断是继续递归还是回溯
                   P[index]=i;
                   isInP[i]=true;
                   generateP(index+1);
                   isInP[i]=false;
               }
            }
        }
    }

    public static void main(String[] args) {
        N=8;
        generateP(1);
        System.out.println(cnt);
    }
}