簡單易懂回溯算法

1、什麼是回溯算法算法

回溯算法實際上一個相似枚舉的搜索嘗試過程,主要是在搜索嘗試過程當中尋找問題的解,當發現已不知足求解條件時,就「回溯」返回,嘗試別的路徑。許多複雜的,規模較大的問題均可以使用回溯法,有「通用解題方法」的美稱。編程

回溯算法實際上一個相似枚舉的深度優先搜索嘗試過程,主要是在搜索嘗試過程當中尋找問題的解,當發現已不知足求解條件時,就「回溯」返回(也就是遞歸返回),嘗試別的路徑。數組

2、回溯算法思想數據結構

  回溯法通常都用在要給出多個能夠實現最終條件的解的最終形式。回溯法要求對解要添加一些約束條件。總的來講,若是要解決一個回溯法的問題,一般要肯定三個元素:函數

一、選擇。對於每一個特定的解,確定是由一步步構建而來的,而每一步怎麼構建,確定都是有限個選擇,要怎麼選擇,這個要知道;同時,在編程時候要定下,優先或合法的每一步選擇的順序,通常是經過多個if或者for循環來排列。學習

二、條件。對於每一個特定的解的某一步,他必然要符合某個解要求符合的條件,若是不符合條件,就要回溯,其實回溯也就是遞歸調用的返回。spa

三、結束。當到達一個特定結束條件時候,就認爲這個一步步構建的解是符合要求的解了。把解存下來或者打印出來。對於這一步來講,有時候也能夠另外寫一個issolution函數來進行判斷。注意,當到達第三步後,有時候還須要構建一個數據結構,把符合要求的解存起來,便於當獲得全部解後,把解空間輸出來。這個數據結構必須是全局的,做爲參數之一傳遞給遞歸函數。設計

3、遞歸函數的參數的選擇,要遵循四個原則code

一、必需要有一個臨時變量(能夠就直接傳遞一個字面量或者常量進去)傳遞不完整的解,由於每一步選擇後,暫時還沒構成完整的解,這個時候這個選擇的不完整解,也要想辦法傳遞給遞歸函數。也就是,把每次遞歸的不一樣狀況傳遞給遞歸調用的函數。blog

二、能夠有一個全局變量,用來存儲完整的每一個解,通常是個集合容器(也不必定要有這樣一個變量,由於每次符合結束條件,不完整解就是完整解了,直接打印便可)。

三、最重要的一點,必定要在參數設計中,能夠獲得結束條件。一個選擇是能夠傳遞一個量n,也許是數組的長度,也許是數量,等等。

四、要保證遞歸函數返回後,狀態能夠恢復到遞歸前,以此達到真正回溯。

4、學習例題

1.給出 n 表明生成括號的對數,請你寫出一個函數,使其可以生成全部可能的而且有效的括號組合。

例如,給出 = 3,生成結果爲:

[

  "((()))",

  "(()())",

  "(())()",

  "()(())",

  "()()()"

]

 

2.思路

首先利用回溯枚舉出全部括號的可能性,而後進行判斷是否符合要求(n對而且是有效的括號組合),就添加到list表格中。

對於遞歸函數變量須要全局變量列表list:用來存儲符合要求的括號組合。

                    局部變量temp:表示當前函數的括號組成樣式。

                    計數器x:判斷遞歸次數,限制其底界。

                    總的造成括號對數n。

3.代碼(力扣中國第22題)

public List<String> generateParenthesis(int n) {
        List<String> list=new ArrayList<String>();
        add_list(list,"(", 1, n*2);       
        return list;
    }
    
    //書寫遞歸函數
    
    public void add_list(List<String> list,String temp,int x,int n)    
    {
        x++;
        if(x<=n)
        {
          add_list(list,temp+"(",x,n);
          add_list(list,temp+")",x,n);
            
        }
        if(x>n)
        {
            //在這裏寫判斷條件是否負荷有效的括號組合
            char[] k=temp.toCharArray();
            //計數器
            int timer=0;
            for(int i=0;i<k.length;i++)
            {
                if(timer<0||timer>n/2)
                {
                    return;
                }
                else
                {
                    if(k[i]=='(')
                      {
                          timer++;
                      }else
                      {
                          timer--;                          
                      }
                }             
            }
            if(timer==0)
            list.add(temp);
        }
        
    }
相關文章
相關標籤/搜索