算法->常见的回溯算法

100 阅读1分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第24天,点击查看活动详情

九宫格规则

规则

  1. 把1放到第一行的中间
  2. 开始向右上角放入后面的数字
  • 如果右上是空的,直接填入
  • 如果右上已经填过了,直接填在当前位置的下面

九宫格->代码实现

public class Jiugongge {
    @Test
    public void test(){
        squaredUp(array);
        for (int i = 0; i < array.length; i++) {
            for (int j = 0; j < array.length; j++) {
                System.out.print(array[i][j]+" ");
            }
            System.out.println();
        }
    }
    public static int n=5;
    public static int[][] array=new int[n][n];
    //逻辑
    public static void squaredUp(int[][] array){
        int x=1;//要填入的数据
        //定义起始位置
        int row=0;
        int col=n/2;
        array[row][col]=1;
        //开始填写后面的数据
        while(x<n*n){
            //在选择下一位置的时候,先记录下现在的位置
            int tempRow=row;
            int tempCol=col;
            //向右上移动
            row--;
            if(row<0){
                row=n-1;
            }
            col++;
            if(col==n){
                col=0;
            }
            x++;
            if(array[row][col]==0){//如果右上没填,直接填入
                array[row][col]=x;
            }else{//如果没填,就放到当前位置的下面
                //还原
                row=tempRow;
                col=tempCol;
                row++;
                array[row][col]=x;
            }
        }
    }
}

八皇后

在8×8格的国际象棋上摆放8个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行、同一列或同一斜线上。

八皇后->代码实现

public class EightQueens {
    @Test
    public void test(){
        eightQueens();

    }
    //下标表示行号    值表示列号
    public static int[] array=new int[8];
    /**
     * 处理八个皇后的问题
     */
    public static void eightQueens(){
        eightQueens(0);
    }
    public static void eightQueens(int row){
        //如果有结果了就退出
        if(row==8){
            printResult();
            System.out.println("---------");
            return;
        }

        //开始从第一列到最后一列一个个放入
        for(int col=0;col<8;col++){
            array[row]=col;
            if(judge(row)){//判断是否可以放入
                eightQueens(row+1);//就开始下一行
            }
        }
    }

    /**
     * 判断当前列放入的位置是否和以前放过的内容有冲突
     */
    public static boolean judge(int n){//n=4
        for(int i=0;i<n;i++){
            //条件1  array[i]==array[n]  在一列上
            //条件2  abs(n-i)==abs(array[n]-array[i])
            if(array[i]==array[n] || Math.abs(n-i)==Math.abs(array[n]-array[i])){
                return false;
            }
        }
        return true;
    }
    public static void printResult(){
        for (int i = 0; i < array.length; i++) {
            System.out.print(array[i]+" ");
        }
        System.out.println();
    }
}

数独

数独规则:将1~9填入9x9的盘面中,使每行、每列、每个粗线宫(3x3)内均不重复。

行:横排,从上到下依次为第19行,记作 R1R9 或 r1~r9;

列:竖排,从左到右依次为第19列,记作 C1C9 或 c1~c9;

宫:粗线围住的3x3小九宫,从左到右、从上到下依次为第19宫,记作 B1B9 或 b1~b9;

数独->代码实现

public class Sudoku {
    @Test
    public void test(){
        sudoku();
    }
    public static int[][] result=new int[9][9];

    public static void sudoku(){
        sudoku(0,0);
    }
    public static void sudoku(int i,int j){
        if(i==8 && j==9){
            printResult();
            return;
        }
        if(j==9){//横着放的时候,如果到了最右边,就回到下一行的第一个
            i++;
            j=0;
        }
        if(result[i][j]==0){//如果是空格
            for (int k = 1; k <= 9; k++) {
                if(judge(i,j,k)){
                    result[i][j]=k;
                    sudoku(i,j+1);
                    //让前一次的格子还原
                    result[i][j]=0;
                }
            }
        }else{
            sudoku(i,j+1);
        }
    }

    /**
     *判断当前位置上是否可以放入数字
     */
    public static boolean judge(int row,int col,int number){
        //判断行和列不重复
        for (int i = 0; i < 9; i++) {
            if(result[row][i]==number || result[i][col]==number){
                return false;
            }
        }
        //判断自已所在的宫里面没有重复值
        int tempRow=row/3;
        int tempCol=col/3;
        for (int i = 0; i < 3; i++) {
            for (int j = 0; j < 3; j++) {
                if(result[tempRow*3+i][tempCol*3+j]==number){
                    return false;
                }
            }
        }
        return true;
    }

    public static void printResult(){
        for (int i = 0; i < 9; i++) {
            for (int j = 0; j < 9; j++) {
                System.out.print(result[i][j]+" ");
            }
            System.out.println();
        }
        System.out.println("-----------------");
    }
}