递归程序实例

来源:互联网 发布:淘宝粉丝怎么看 编辑:程序博客网 时间:2024/06/03 21:30

1.Valid Sudoku

There are just 3 rules to Sudoku.

Each row must have the numbers 1-9 occuring just once.
Each column must have the numbers 1-9 occuring just once.
And the numbers 1-9 must occur just once in each of the 9 sub-boxes of the grid.


Determine if a Sudoku is valid, according to: Sudoku Puzzles - The Rules.

The Sudoku board could be partially filled, where empty cells are filled with the character'.'.


A partially filled sudoku which is valid.

当然这里用不到递归,下面的问题就要用到递归了。看起来比较复杂,实际比较简单,根据规则进行判断就行了。这里判重采用的map的方式

代码:

public class Solution {    //置为静态变量    static Map<Character,Integer> map = new HashMap<Character,Integer>();    public boolean isValidSudoku(char[][] board) {        //判断每行        for(int i = 0; i < board.length; i++){            initMap();//每次均需初始化            for(int j = 0; j < board[0].length; j++){                //是数字                if(board[i][j] >= '0' && board[i][j] <= '9'){                    if(map.get(board[i][j]) > 0){//说明重复数字                        return false;                    }else{                        map.put(board[i][j],1);                    }                }else if(board[i][j] != '.'){//出现空格和0-9之外的字符                    return false;//直接返回false                }            }        }                //判断每列        for(int i = 0; i < board[0].length; i++){            initMap();//每次均需初始化            for(int j = 0; j < board.length; j++){                //是数字                if(board[j][i] >= '0' && board[j][i] <= '9'){                    if(map.get(board[j][i]) > 0){//说明重复数字                        return false;                    }else{                        map.put(board[j][i],1);                    }                }else if(board[j][i] != '.'){//出现空格和0-9之外的字符                    return false;//直接返回false                }            }        }                //判断九宫格        for(int i = 0; i < board.length - 2; i = i+3){//行{            for(int j = 0; j < board[0].length - 2; j=j+3){                initMap();//初始化                for(int m = i; m < i + 3;m++){                    for(int n = j; n < j+3; n++){                        //是数字                        if(board[m][n] >= '0' && board[m][n] <= '9'){                            if(map.get(board[m][n]) > 0){//说明重复数字                                return false;                            }else{                                map.put(board[m][n],1);                            }                        }else if(board[m][n] != '.'){//出现空格和0-9之外的字符                            return false;//直接返回false                        }                    }                }            }        }                return true;    }        //初始化map为每个key均赋值0    private void initMap(){        for(char i = '0';i <= '9'; i++){            map.put(i,0);        }    }}

2.Sudoku Solver

Write a program to solve a Sudoku puzzle by filling the empty cells.

Empty cells are indicated by the character '.'.

You may assume that there will be only one unique solution.


A sudoku puzzle...


...and its solution numbers marked in red.

这里是要求求出具体的方案,思路跟八皇后问题是一样的。递归处理即可。


class Solution {public:    bool dfs (vector<vector<char> > &board, int i, int j, int n ) { //函数写成return bool型,这样在找到第一个解的时候return.          if (j >= n) {            return dfs(board, i+1, 0, n);          } else if (i == n){              return true;          } else if (board[i][j] != '.'){              return dfs(board, i, j+1, n);          } else {              for (int k = 1; k <= n; ++k){                  board[i][j] = (char)('0' + k);                  if (isValid(board, i, j, n)){                      if (dfs(board, i, j+1 , n))  // 如果找到第一个解,就及时return                          return true;                  }                board[i][j] = '.';            }        }        return false;    }        bool isValid(vector<vector<char>> &board, int i , int j, int n) {          for (int index = 0; index < n; ++index){              if (index != j && board[i][index] == board[i][j]) {                  return false;              }          }            for (int index = 0; index < n; ++index){              if (index != i && board[index][j] == board[i][j]) {                  return false;              }          }                int index_i = i / 3;          int index_j = j / 3;                    for (int x = index_i * 3; x < index_i * 3 + 3; ++x) {              for (int y = index_j * 3; y < index_j * 3 + 3; ++y) {                  if ((x!=i || y != j) && board[x][y] == board[i][j]) { //注意这里逻辑是"或"||,不是"与"                      return false;                  }              }          }          return true;      }        void solveSudoku(vector<vector<char> > &board) {          if (board.size() == 0 || board[0].size() == 0) return;         dfs(board, 0, 0, 9);    }};

3.N-Queens

The n-queens puzzle is the problem of placing n queens on ann×n chessboard such that no two queens attack each other.

Given an integer n, return all distinct solutions to the n-queens puzzle.

Each solution contains a distinct board configuration of the n-queens' placement, where'Q' and'.' both indicate a queen and an empty space respectively.

For example,
There exist two distinct solutions to the 4-queens puzzle:

[ [".Q..",  // Solution 1  "...Q",  "Q...",  "..Q."], ["..Q.",  // Solution 2  "Q...",  "...Q",  ".Q.."]]

可以有不同的方法,一种方法就是同第2题中的方法一样,每个位置进行递归,这样需要有一个棋盘,浪费了一定的空间,但是比较好理解;第二种方法,把每一行所放置的数字连起来可以看成N个数字的排列。关于生成排列的几种算法可以参考《排列组合程序》。

代码如下:

public class Solution {    public List<List<String>> solveNQueens(int n) {        ArrayList<List<String>> res = new ArrayList<List<String>>();        int[] nums = new int[n];        for(int i = 0;i<n;i++) nums[i] = i;        helper(nums,0,res);        return res;    }        public void helper(int[] nums,int pos,List<List<String>> res){        if(pos == nums.length){            save(nums,res);            return;        }        for(int i = pos;i < nums.length;i++){            swap(nums,pos,i);            if(isValidate(nums,pos))                helper(nums,pos+1,res);            swap(nums,pos,i);        }    }        public void save(int[] nums,List<List<String>> res){        ArrayList<String> tmp = new ArrayList<String>();        for(int i = 0;i < nums.length;i++){            StringBuilder sb = new StringBuilder();            for(int j = 0;j < nums.length;j++){                if(nums[i] != j) sb.append(".");                else sb.append("Q");            }            tmp.add(sb.toString());        }        res.add(tmp);    }    public void swap(int[] nums,int i,int j){        int tmp = nums[i];        nums[i] = nums[j];        nums[j] = tmp;    }    public boolean isValidate(int[] nums,int pos){        for(int i = 0;i < pos;i++){            if((i+nums[i] == pos+nums[pos]) || (i-nums[i] == pos-nums[pos])) return false;        }        return true;    }}

4.N-Queens II

Follow up for N-Queens problem.

Now, instead outputting board configurations, return the total number of distinct solutions.


同上一道题一样,代码如下:

public class Solution {    private int count = 0;    public int totalNQueens(int n) {        int[] nums = new int[n];        for(int i = 0;i<n;i++) nums[i] = i;        helper(nums,0);        return count;    }    public void helper(int[] nums,int pos){        if(pos == nums.length){            count++;            return;        }else{            for(int i = pos;i < nums.length;i++){                swap(nums,pos,i);                if(isValidate(nums,pos))                    helper(nums,pos+1);                swap(nums,pos,i);            }        }    }    public void swap(int[]nums,int i,int j){        int tmp = nums[i];        nums[i] = nums[j];        nums[j] = tmp;    }    public boolean isValidate(int[] nums,int pos){        for(int i = 0;i < pos;i++) if((i+nums[i] == pos+nums[pos])||(i-nums[i] == pos-nums[pos])) return false;        return true;    }}








1 0