51/52. N-Queens -- 待优化

经典的八皇后问题,

queen 可以攻击的范围:  水平,垂直,斜向, 放置 queen 让所有的queens 不在对方的攻击范围内,问有多少种方法或者产生相应的棋盘。

分析: 依次产生每一行的结果, 先在某行某个位置放一个结果,如果不能产生解 则back tracking 到上一行,重新放置。

以 n=4 为例,每个位置都得分解 n=4 份, 算法复杂度为 n^n ,是一个很高的结果,因此当 n>12 时,测试用例都会TLE。

需要解决的问题:

1. 如果存储 每个位置, 可以定义一个Node {int i, int j} 来标记index, 也可以 在二维矩阵中 用 i*n +j 来唯一的标志位置,只是每次需要 用除法和mod 来计算 i, j 。

给出一个代码, 但代码只排到 10%左右, 需要进一步优化:

class Solution {
    public List<List<String>> solveNQueens(int n) {
       List<List<Integer>> result = new ArrayList<>();
       dfs(new ArrayList<>(), result,0,n);
       return generate_results(result,n);
    }

    private List<List<String>> generate_results(List<List<Integer>> result,int n){
        StringBuilder init_str = new StringBuilder();
        for(int i=0; i<n; i++){
            init_str.append(".");
        }
        //System.out.println(init_str);

        List<List<String>> re_resu = new ArrayList<>();
        for(List<Integer> cur: result){
            List<String> cur_str = new ArrayList<>();
            for(int val: cur){
                int j = val%n;
                init_str.setCharAt(j,‘Q‘);
                cur_str.add(init_str.toString());
                //System.out.println(cur_str);
                init_str.setCharAt(j,‘.‘);
            }
            re_resu.add(new ArrayList<>(cur_str));
        }
        return re_resu;
    }

    private void dfs(List<Integer> curResult, List<List<Integer>> result, int rows,int n){
        if(curResult.size() == n){
            result.add(new ArrayList<>(curResult));
            //System.out.println(curResult);
            return ;
        }

        if(rows>=n) return;

        for(int i=0; i<n; i++){
            int candid = rows*n +i;
            if(isValid(curResult, candid,n)){
                curResult.add(candid);
                dfs(curResult,result,rows+1,n);
                curResult.remove(curResult.size()-1);
            }
        }
    }

    private boolean isValid(List<Integer> curResult, int candid, int n){
        int i = candid/n;
        int j = candid%n;

        // 水平 and 垂直
        for(int cur: curResult){
            int cur_i = cur/n;
            int cur_j = cur%n;
            if(i == cur_i || j== cur_j) return false;
        }

        int x = 0;
        //斜向:left up
        for(x =0; x<n; x++){
            if(i-x <0 || j-x<0) break;
            int left_up = (i-x)*n + (j-x);
            if(curResult.contains(left_up)) return false;
        }
        // right down
        for(x=0; x<n; x++){
            if(i+x>=n || j+x >=n) break;
            int right_down = (i+x)*n + j+x;
            if(curResult.contains(right_down)) return false;
        }

        //right up
        for(x=0; x<n; x++){
            if(i-x<0 || j+x>=n) break;
            int right_up = (i-x) *n +j+x;
            if(curResult.contains(right_up)) return false;
        }
        //left down
        for(x=0; x<n; x++){
            if(i+x>=n|| j-x<0) break;
            int left_down = (i+x)*n + j-x;
            if(curResult.contains(left_down)) return false;
        }
        return true;
    }
}

原文地址:https://www.cnblogs.com/keepAC/p/9973798.html

时间: 2024-11-01 20:51:55

51/52. N-Queens -- 待优化的相关文章

那些年,一起学的Java 5-1 5-2

/**5-1 * 定义接口Printable,其中包括一个方法printItMyWay(), * 这个方法没有形参,返回值为空 **/ interface Printable { void printItMyWay(); } /**5-2 * 改写实验3中的矩形类,使之实现Printable接口, * 用printItMyWay()方法将矩形的相关信息(长.宽.周长.面积) * 打印在屏幕上; * 改写实验4中的正方形类,重载printItMyWay()方法 * 将正方形的相关信息(边长.周长.

[email&#160;protected] [51/52] N-Queens

https://leetcode.com/problems/n-queens/ 1 class Solution { 2 public: 3 void dfs(vector<vector<string>> &ret, vector<vector<char>> map,int i, int j){ 4 if(i==map.size()-1){ 5 vector<string> ans; ans.clear(); 6 for(int ki=0

[LeetCode 51&amp;52] N-Queens I &amp; II (N皇后问题)

题目链接:n-queens import java.util.ArrayList; import java.util.Arrays; import java.util.List; /** * The n-queens puzzle is the problem of placing n queens on an n×n chessboard such that no two queens attack each other. Given an integer n, return all dist

leetcode#52 N queensⅡ

n 皇后问题研究的是如何将 n 个皇后放置在 n×n 的棋盘上,并且使皇后彼此之间不能相互攻击. 上图为 8 皇后问题的一种解法. 给定一个整数 n,返回 n 皇后不同的解决方案的数量. 示例: 输入: 4 输出: 2 解释: 4 皇后问题存在如下两个不同的解法. [  [".Q..",  // 解法 1   "...Q",   "Q...",   "..Q."],  ["..Q.",  // 解法 2  

如何简单实现接口自动化测试(基于 python) 原博主地址https://blog.csdn.net/gitchat/article/details/77849725

如何简单实现接口自动化测试(基于 python) 2017年09月05日 11:52:25 阅读数:9904 GitChat 作者:饿了么技术社区 原文:如何简单实现接口自动化测试(基于 python) 关注微信公众号:GitChat 技术杂谈 ,这里一本正经的讲技术 一.简介 本文从一个简单的登录接口测试入手,一步步调整优化接口调用姿势,然后简单讨论了一下接口测试框架的要点,最后介绍了一下我们目前正在使用的接口测试框架pithy.期望读者可以通过本文对接口自动化测试有一个大致的了解. 二.引言

HDU - 3790 最短路径问题(Dijkstra+优先队列优化)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3790 题意:中文题(边被赋予两种属性,一种是路径,一种是花费),然后略.(逃...... 今天看了卿学姐的视频,初尝SPFA和Dijkstra. 一个是用队列优化,一个是用优先队列优化.这道题目用这两种方法都可以. dijkstra算法思想(贪心):从距离起点最近的点开始,从这个点遍历一遍它周围的点,进行松弛操作,直到最终点. 整个的算法思想就是贪心,每次都给它形成最短路. 这道题目值得注意的是预处

Bzoj 1563: [NOI2009]诗人小G(决策单调性优化)

原题面 带有详细证明的转这里 题意:每一个线段有一个长度,有一个标准长,现在要把这些线段按照顺序分行,每行的不和谐值等于标准长和该行线段总长的差的绝对值的p次方.现在要求最小的不和谐值之和. 开始的时候完全读错题了,以为p==2 for ever.真是太天真.后来看数据范围才发现.我真是面向数据编程? n^2的dp是一眼秒的.然后如果是p=2,那就是一个非常像玩具装箱的斜率优化dp.对于4.5的数据范围.可以想到用贪心优化dp.因为每一行的长度不会通过拼接线段(线段条数>=2)达到2*标准长,这

三种快速排序以及快速排序的优化

一.  快速排序的基本思想 快速排序使用分治的思想,通过一趟排序将待排序列分割成两部分,其中一部分记录的关键字均比另一部分记录的关键字小.之后分别对这两部分记录继续进行排序,以达到整个序列有序的目的. 二.  快速排序的三个步骤 1) 选择基准:在待排序列中,按照某种方式挑出一个元素,作为 "基准"(pivot): 2) 分割操作:以该基准在序列中的实际位置,把序列分成两个子序列.此时,在基准左边的元素都比该基准小,在基准右边的元素都比基准大: 3) 递归地对两个序列进行快速排序,直到

hdu 3507 斜率优化

我的第一道斜率优化. 就这道题而言,写出原始的方程: dp[i] = min{ dp[j] + (sum[i]-sum[j])2  + M | j in [0,i) } O(n^2)的复杂度肯定超时,要么优化转移,要么重写方程. 斜率优化的思想就是减少不必要的枚举(即不枚举肯定不会成为决策点的j). 我们考虑两个位置p<q<i “选择q比选择p优” 当且仅当 dp[q]+(sum[i]-sum[q])2+M < dp[p]+(sum[i]-sum[p])2+M 化简右边即: [ (dp[