遞歸2-回溯與遞歸

I. 回溯算法基礎(chǔ)
  • 回溯與遞歸的區(qū)別和聯(lián)系
    ? 很多人不理解回溯與遞歸到底是什么關(guān)系谬返。其實很簡單,回溯算法是一種算法思想,是我們解決問題的策略铺董;而遞歸是一種算法結(jié)構(gòu)。遞歸就是函數(shù)調(diào)用本身禀晓,一般回溯法多用遞歸來實現(xiàn)精续。
  • 回溯法的基本思想
    ? 在按某種搜索策略搜索的過程中,當(dāng)?shù)竭_(dá)某一狀態(tài)時粹懒,繼續(xù)向前搜索已經(jīng)確定不會得到正確答案的情況下重付,可以返回上一搜索狀態(tài),沿著新的可能性繼續(xù)搜索凫乖。其求解過程的實質(zhì)是一個先序遍歷一棵“狀態(tài)樹”的過程确垫。
  • 回溯法的特點
    1. 搜索策略:符合遞歸算法,問題解決可以化為子問題帽芽,算法類似删掀,規(guī)模減小;
    2. 控制策略:當(dāng)遇到失敗的搜索狀態(tài),需要返回上一狀態(tài)导街,沿另外的路徑搜索;
    3. 數(shù)據(jù)結(jié)構(gòu):一般用數(shù)組保存搜索過程中的狀態(tài)披泪、路徑。
II. 回溯法的經(jīng)典例子
  • 爬樓梯問題

? 對于一個與 n 級臺階組成的樓梯搬瑰,爬樓梯時一次可以上 1 級臺階或 2 級臺階款票。共有多少種不同的走法。
1. 問題分析
?由題可知泽论,在任何一級臺階我們往上爬的時候都有兩種選擇:爬 1 級臺階或者爬2 級臺階艾少。那就會產(chǎn)生回溯,當(dāng)我們爬 2 級臺階會超出樓梯時翼悴,我們再返回來爬 1 級臺階;其次缚够,n 級臺階可能是由第 n-1 級臺階爬上來的,也可能是從第 n-2 級臺 階爬上來的抄瓦。所以潮瓶,對于 n 級臺階的問題又可以分解成為兩個相似的字問題。符合遞歸的條件钙姊。
2. Java代碼實現(xiàn)

/**
* @Author: 落腳丶
* @Date: 2017/10/15
* @Time: 上午11:24
* @ClassName: ClimbStairs
* @Description: 爬樓梯方法的回溯解法
*/
public class ClimbStairs {
 static int s = 1;
 public static int[] steps = new int[10];

 public static void main(String[] args){
     System.out.println("請輸入臺階數(shù):");
     Scanner scanner = new Scanner(System.in);
     int n = scanner.nextInt();
     tryStep(n);
 }
 static void tryStep(int n){ // 爬n級樓梯
     for (int i = 1; i <= 2; i++){
         // 對于每次爬有兩次嘗試毯辅,一次爬1級或者一次爬2級
         if (n < i)
             break;
         steps[s++] = i; // 一步走了i級臺階
         n -= i; //縮小問題的規(guī)模
         if (n == 0) {
             for (int j = 1; j < s; j++){
                 System.out.print("第"+ j + "步走了" + steps[j] 
                 + "級臺階 ");
             }
             System.out.println();
         } else {
             tryStep(n);
         }
         n += i;
         steps[s--] = 0;
     }
 }
}
/**
* 以4級臺階為例的輸出:
*
* 請輸入臺階數(shù):
* 4
* 第1步走了1級臺階 第2步走了1級臺階 第3步走了1級臺階 第4步走了1級臺階
* 第1步走了1級臺階 第2步走了1級臺階 第3步走了2級臺階
* 第1步走了1級臺階 第2步走了2級臺階 第3步走了1級臺階
* 第1步走了2級臺階 第2步走了1級臺階 第3步走了1級臺階
* 第1步走了2級臺階 第2步走了2級臺階 
*/
  • 八皇后問題

    ? 在國際象棋棋盤8 × 8上放置八個皇后,使得任意兩個皇后之間不能在同一行煞额,同一列思恐,也不能位于同于對角線上沾谜。問共有多少種不同的方法,并且指出各種不同的放法胀莹。
    1. 算法思路:
    ? 我們知道基跑,假如不考慮題中的限制,每行放置皇后都有 8 種放法描焰,我們可以用一個完全八叉樹來描述整個過程媳否。而實際問題中我們需要根據(jù)條件來對樹進(jìn)行枝。
    ? 我們可以定義一個數(shù)組 position[8]荆秦,其中 position[i] = j 代表第 i 行 j 列篱竭。于是,約束條件可以如下表示:
    a. 不在同一列:position[i] != position[j];
    b. 不在對角線上:|i ? j| != |position[i] ? position[j]|.

    ? 從第一行確定第 1 個皇后的位置步绸,然后在第二行搜索第 2 個皇后的位置掺逼,... , 每前進(jìn)一步檢查是否滿足約束條件瓤介,不滿足約束條件的時候回溯到上一個皇后的位置吕喘,嘗試該行其他列是否滿足條件,直到找到問題解刑桑。
    2. 算法的Java實現(xiàn):

/**
 * @Author: 落腳丶
 * @Date: 2017/10/18
 * @Time: 下午4:55
 * @ClassName: EightQueen
 * @Description: 8皇后問題回溯解法
 */
public class EightQueen {
    private static int num = 1; // 方案的總數(shù)
    private static final int MAX_QUEEN = 8;
    private static int[] position = new int[MAX_QUEEN];

    public static void main(String[] args) {
        trail(0);
    }
    /**
    * @Date: 2017/10/18
    * @Time: 下午5:00
    * @Method: isValid
    * @Return: 位置是否滿足條件
    * @Description: 判斷位置是否滿足條件
    */

    static boolean isValid(int row) {
        for (int i = 0; i < row; i++) {
            /**
             * 如果前面放好的位置不在同一行氯质、同一列、同一對角線
             * 則返回true
             * 否則返回false
             */
            if (position[i] == position[row] ||
                    Math.abs(position[i] - position[row]) ==
                    Math.abs(i - row) ) {
                return false;
            }
        }
        return true;
    }

    /**
    * @Date: 2017/10/18
    * @Time: 下午5:29
    * @Method: print
    * @Description: 打印皇后擺放位置的結(jié)果
    */
    static void print() {
        System.out.println("第" + num++ +"種擺法:");
        for (int i = 0; i < MAX_QUEEN; i++) {
            for (int j = 0; j < MAX_QUEEN; j++) {
                if(position[i] == j)
                    System.out.print("+ ");
                else
                    System.out.print("0 ");
            }
            System.out.println();
        }
        System.out.println();
    }

    static void trail(int row) {
        // 如果擺完MAX_QUEEN行漾月,則輸出結(jié)果
        if (row == MAX_QUEEN) {
            print();
            return;
        }
        for (int column = 0; column < MAX_QUEEN; column++) {
            position[row] = column; // 放在第row行第column列
            // 如果滿足條件病梢,則進(jìn)行下一行
            if (isValid(row))
                trail(row + 1);
        }
    }
}

部分輸出結(jié)果(合成圖片):


結(jié)果展示.jpg
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市梁肿,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌觅彰,老刑警劉巖吩蔑,帶你破解...
    沈念sama閱讀 217,907評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異填抬,居然都是意外死亡烛芬,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,987評論 3 395
  • 文/潘曉璐 我一進(jìn)店門飒责,熙熙樓的掌柜王于貴愁眉苦臉地迎上來赘娄,“玉大人,你說我怎么就攤上這事宏蛉∏簿剩” “怎么了?”我有些...
    開封第一講書人閱讀 164,298評論 0 354
  • 文/不壞的土叔 我叫張陵拾并,是天一觀的道長揍堰。 經(jīng)常有香客問我鹏浅,道長,這世上最難降的妖魔是什么屏歹? 我笑而不...
    開封第一講書人閱讀 58,586評論 1 293
  • 正文 為了忘掉前任隐砸,我火速辦了婚禮,結(jié)果婚禮上蝙眶,老公的妹妹穿的比我還像新娘季希。我一直安慰自己,他們只是感情好幽纷,可當(dāng)我...
    茶點故事閱讀 67,633評論 6 392
  • 文/花漫 我一把揭開白布式塌。 她就那樣靜靜地躺著,像睡著了一般霹崎。 火紅的嫁衣襯著肌膚如雪珊搀。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,488評論 1 302
  • 那天尾菇,我揣著相機(jī)與錄音境析,去河邊找鬼。 笑死派诬,一個胖子當(dāng)著我的面吹牛劳淆,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播默赂,決...
    沈念sama閱讀 40,275評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼沛鸵,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了缆八?” 一聲冷哼從身側(cè)響起曲掰,我...
    開封第一講書人閱讀 39,176評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎奈辰,沒想到半個月后栏妖,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,619評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡奖恰,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,819評論 3 336
  • 正文 我和宋清朗相戀三年吊趾,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片瑟啃。...
    茶點故事閱讀 39,932評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡论泛,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出蛹屿,到底是詐尸還是另有隱情屁奏,我是刑警寧澤,帶...
    沈念sama閱讀 35,655評論 5 346
  • 正文 年R本政府宣布蜡峰,位于F島的核電站了袁,受9級特大地震影響朗恳,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜载绿,卻給世界環(huán)境...
    茶點故事閱讀 41,265評論 3 329
  • 文/蒙蒙 一粥诫、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧崭庸,春花似錦怀浆、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,871評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至函筋,卻和暖如春沙合,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背跌帐。 一陣腳步聲響...
    開封第一講書人閱讀 32,994評論 1 269
  • 我被黑心中介騙來泰國打工首懈, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人谨敛。 一個月前我還...
    沈念sama閱讀 48,095評論 3 370
  • 正文 我出身青樓究履,卻偏偏與公主長得像,于是被迫代替她去往敵國和親脸狸。 傳聞我的和親對象是個殘疾皇子最仑,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,884評論 2 354

推薦閱讀更多精彩內(nèi)容

  • 回溯算法 回溯法:也稱為試探法,它并不考慮問題規(guī)模的大小炊甲,而是從問題的最明顯的最小規(guī)模開始逐步求解出可能的答案泥彤,并...
    fredal閱讀 13,657評論 0 89
  • 背景 一年多以前我在知乎上答了有關(guān)LeetCode的問題, 分享了一些自己做題目的經(jīng)驗。 張土汪:刷leetcod...
    土汪閱讀 12,744評論 0 33
  • LeetCode 刷題隨手記 - 第一部分 前 256 題(非會員)卿啡,僅算法題全景,的吐槽 https://leetc...
    蕾娜漢默閱讀 17,778評論 2 36
  • 貪心算法 貪心算法總是作出在當(dāng)前看來最好的選擇。也就是說貪心算法并不從整體最優(yōu)考慮牵囤,它所作出的選擇只是在某種意義上...
    fredal閱讀 9,231評論 3 52
  • 昨天在公交車上狠狠地哭了一通揭鳞,像斷線的珠子一大滴一大滴的。 坐隔壁的隔壁的中年男人用復(fù)雜的眼神看著我梆奈,但我又有什么...
    巫女不WU閱讀 437評論 0 1