日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

算法 递归与回溯

發布時間:2024/4/17 编程问答 24 豆豆
生活随笔 收集整理的這篇文章主要介紹了 算法 递归与回溯 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

遞歸

遞歸是利用方法幀后進先出的特點。先進入的方法棧幀等待后進入的方法棧幀計算結果。例如:f(n)=f(n-1)+1,f(n)等待f(n-1)的結果,依次遞歸向下優先算出最低層結果后,再依次返回根據下層結果計算。

:一層一層深入(依次執行前置代碼),直到到達遞歸終止條件(一定要有終止條件,不再執行自己)。

等待下層方法棧幀執行完成/return結果......

:再從底層一層一層返回(依次執行后置代碼)。利用JAVA方法棧幀局部變量獨立的特性,保證退回棧幀時狀態為原始狀態。

遞歸也是循環的一種表現,不過比循環更容易執行多層回退、前序后序操作。但是遞歸因為要重復的創建棧幀所以效率沒有循環高。

遞歸思想,開發人員只要把設計重心放到設計一步操作的統一模板即可,包含進入到這一步執行的代碼,是否可以進入下一步,返回當前步驟后繼續執行的代碼。

循環代替

一般循環也可以用while循環執行回退,但是比較麻煩。需要借助一個Stack數據結構保存各步狀態,并且手動遞增和回退,并保證正確性。

?

常涉及的算法思想

分治思想:

快速排序:典型的遞歸前置思想,先執行取中分邊,再左右向下遞歸

歸并排序:典型的遞歸后置思想,先取中左右向下遞歸,再從最底層一層層向上執行歸并。

回溯思想:

DFS,斐波那契.....等等

?

2 復用避免重復計算

? ?可以適當配和動態規劃思想,遞歸時可以把各步結果保存,可以復用。?斐波那契數列就是典型例子

3? 斐波那契數

//遞歸方式實現斐波那契數public static long rec_fib(long i) {long result = 0;if(i <= 0) return 0; //遞歸終止if(i == 1 || i == 2) //遞歸終止result = 1;else {System.out.println("遞歸前置");result = rec_fib(i-1) //返回繼續 <=======> 進入下層+ rec_fib(i-2); //返回繼續 <=======> 進入下層System.out.println("遞歸后置");}return result;}

回溯算法

回溯算法很符合人類思維邏輯,適用范圍非常廣泛。

回溯算法是一種試探性算法,也是窮舉法,利用DFS的解決思路,把整個問題想成一個樹形/圖形節點關系,不同的可能代表不同節點分支。從一個節點開始以DFS一步一步向下試探,不滿足條件/目標則退回上一步節點探性其他分支,若沒有剩余分支再退回上一步。其也是遞歸特性的一種經典表現。

明確終止向下試探的邊際條件,?設計遞歸前置代碼處理準備進入下一步之前的工作,遞歸后置代碼處理再次退回當前節點時當前節點需要繼續執行的工作。

典型問題:leetcode39、78

給定一組不含重復元素的整數數組?nums={0,1,2},返回該數組所有可能的子集(冪集)。

按照代碼執行順序:

[],[0],[0,1],[0,1,2],[0,2],[1],?[1,2],[2]

第一層循環:確定子集首位,當遇到第一個選項分支時直接遞歸進入第二層;

第二層循環:確定第二位 ......以此類推,沒有可/未選分支了,再退回上一位,找其他分支。

public static void main(String[] args) {int[] nums = {0,1,2};System.out.println(subsets(nums));}public static List<List<Integer>> subsets(int[] nums) {List<List<Integer>> result = new ArrayList();//結果集(所有子集)List<Integer> temp = new ArrayList();//記錄到當前節點的路過節點(當前路徑)dfs(result,temp,nums,0);return result;}public static void dfs(List<List<Integer>> result, List<Integer> temp, int nums[], int index){result.add(new ArrayList<Integer>(temp));//temp添加到結果集中//從index位置向后for (int i = index; i < nums.length; i++) {//添加第i個數進入temp中temp.add(nums[i]);//進入到下一層,將temp添加到結果集中并添加下一個數dfs(result,temp,nums,i+1); //返回繼續 <=======> 進入下層//從下層返回后,把最新添加的一個數刪掉繼續循環(temp手動回退到本層原狀態)temp.remove(temp.size()-1);}//循環完返回上一層遞歸}

?

轉載于:https://www.cnblogs.com/sw008/p/11054307.html

總結

以上是生活随笔為你收集整理的算法 递归与回溯的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。