leetcode n-queens

N皇后是一个十分经典的问题。

这题一个经典的解法就是回溯法。

一开始使用回溯法的话。陷入了两个误区。

第一,每次回溯都从第一个点开始计算,其实完全没必要。

第二,每次回溯都将当前解空间复制一遍。其实也没有必要。

上网搜了一下解法。核心思想为,因为N皇后问题限制每行只能放一个皇后。所以,考虑以行为维度考虑问题而不是以

点为维度考虑问题。

对于每次递归,检索当前行内所有的点,如果找到一个点就进入下一行。如果当前行所有点都无效,则直接返回。

那么对于解空间的问题。一开始觉得每次分裂出一个新的解,就需要把其上一行的解空间复制一遍,以保证其没有冲突。

其实没有必要这么做,回溯法一个重要的点就是,从头到尾只使用一个解空间,只是当你完成某个维度的检索,返回上一级

维度时,将当前维度的解空间清空即可。这一点在上一个博文permuations中也有体现,他在完成一个维度的检索之后,

再把交换过的元素交换回来。

下面给出代码

import java.util.ArrayList;
import java.util.List;


public class Solution2 {

    /**
     * @param args
     */
     public List<List<String>> solveNQueens(int n) {
         
         ArrayList<List<String>> result=new ArrayList<List<String>>();
         int [][]nums=new int[n][n];
         f(0,0,nums,result);
        return result;
         
     }
     private void f(int x,int y,int[][] nums, ArrayList<List<String>> result)
     {
         
         //p(nums);
        // System.out.println("--------------");
             
         for(int i=0;i<nums.length;i++)
         {
            
             if(test(nums,x,i))
             {
                 nums[x][i]=1;
                 if(x==nums.length-1)
                 {
                     result.add(Convert(nums));
                     break;
                 }
                 
                 f(x+1,0,nums,result);
             }
             nums[x][i]=0;
             
         }
         
    for(int i=0;i<nums.length;i++)
        nums[x][i]=0;
     }
    
      private boolean test(int [][]solution,int x,int y)
      {
          
          for(int i=0;i<solution.length;i++)
              for(int j=0;j<solution[i].length;j++)
              {
                  if(solution[i][j]==1)
                  {  
                      if(x==i||y==j)
                          return false;
                      double gradient=(double)(y-j)/(double)(x-i);
                      
                      if(gradient==1.0||gradient==-1.0)
                          return false;
                  }
              }
          return true;
      
      }
      private ArrayList<String> Convert(int [][]solution)
      {
          ArrayList<String> result=new ArrayList<String>();
         for(int i=0;i<solution.length;i++)
         {
             String tmp="";
             for(int j=0;j<solution[i].length;j++)
             {
                 if(solution[i][j]==0)
                     tmp+=".";
                 else
                     tmp+="Q";
             }
             result.add(tmp);
             
         }
         return result;
      }
    

}

 

posted @ 2016-05-08 19:30  ElNinoT  阅读(181)  评论(0编辑  收藏  举报