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 递归
-
全排列问题
就像一个按顺序填空问题
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);
}
}
-
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);
}
}
- 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);
}
}