摘要:通用算法思路總結初始結果列表。可能要將數集排序,方便處理重復元素的情況。書寫遞歸函數,先要考慮原點狀況,一般就是考慮什么情況下要將當前結果添加到結果列表中。每當一個元素添加到當前結果中之后,要再調用遞歸函數,相當于固定了前綴窮舉后面的變化。
通用算法思路總結:
初始結果列表。
可能要將數集排序,方便處理重復元素的情況。
調用遞歸函數。
書寫遞歸函數,先要考慮原點狀況,一般就是考慮什么情況下要將當前結果添加到結果列表中。
for循環遍歷給定集合所有元素,不同題目區別在于進行循環的條件,具體看例子。每當一個元素添加到當前結果中之后,要再調用遞歸函數,相當于固定了前綴窮舉后面的變化。
調用完之后要將當前結果中最后一個元素去掉,進行下一個循環才不會重復。
如果對于遞歸過程不熟悉的,可以用debug模式觀察參數在遞歸過程中的變化。
舉例包含:
78.Subsets
90.SubsetsII
46.Permuation
77.Combinations
39.Combination Sum
40.Combination Sum II
131.Panlindrome Partitioning
78.Subsets給一個數集(無重復數字),要求列出所有子集。
public class Solution { List90.SubsetsII> res; public List
> subsets(int[] nums) { res = new ArrayList<>(); if(nums.length == 0) return res; List
temp = new ArrayList<>(); helper(nums,temp,0); return res; } private void helper(int[] nums, List temp,int i) { res.add(new ArrayList<>(temp)); for(int n = i; n < nums.length;n++){ temp.add(nums[n]); helper(nums,temp,n+1); temp.remove(temp.size()-1); } } }
給一個數集(有重復數字),要求列出所有子集。
public List46.Permuation> subsetsWithDup(int[] nums) { List
> list = new ArrayList<>(); Arrays.sort(nums); helper(list, new ArrayList<>(), nums, 0); return list; } private void helper(List
> list, List
tempList, int [] nums, int start){ list.add(new ArrayList<>(tempList)); for(int i = start; i < nums.length; i++){ if(i > start && nums[i] == nums[i-1]) continue; // skip duplicates tempList.add(nums[i]); helper(list, tempList, nums, i + 1); tempList.remove(tempList.size() - 1); } }
給一個數集(無重復元素),返回所有排列。
public class Solution { List> result; public List
> permute(int[] nums) { result = new ArrayList<>(); if(nums.length == 0) return result; helper(nums,new ArrayList<>()); return result; } private void helper(int[] nums,List
temp){ if(temp.size() == nums.length) result.add(new ArrayList<>(temp)); else{ for(int i = 0;i 77.Combinations 給一個正整數n,要求返回1-n中k(k<=n)個數所有組合的可能。
public class Solution { List39.Combination Sum> ret; public List
> combine(int n, int k) { ret = new ArrayList<>(); if(n
temp = new ArrayList<>(); helper(start,n,k,temp); return ret; } private void helper(int start,int n,int k,List temp){ if(temp.size() == k){ ret.add(new ArrayList (temp)); } else { for(int i = start;i<=n;i++){ temp.add(i); helper(i+1,n,k,temp); temp.remove(temp.size()-1); } } } } 給一個數集和一個數字target,要求返回 用數集中數字加和等于target的所有組合 (數集中的數可以重復使用)。
public class Solution { List40.Combination Sum II> result; public List
> combinationSum(int[] candidates, int target) { result = new ArrayList<>(); Arrays.sort(candidates); helper(candidates,new ArrayList<>(),target,0); return result; } private void helper(int[] candidates,List
temp, int remain,int start){ if(remain == 0) { result.add(new ArrayList<>(temp)); return; } for(int i = start;i < candidates.length && remain >= candidates[i];i++){ int tempRemain = remain - candidates[i]; if(tempRemain == 0 || tempRemain >= candidates[i]){ temp.add(candidates[i]); //此處用i,因為可以重復使用元素 helper(candidates,temp,tempRemain,i); temp.remove(temp.size()-1); } } } } 給一個數集和一個數字target,要求返回 用數集中數字加和等于target的所有組合 (數集中的數不可以重復使用)。
public class Solution { List131.Panlindrome Partitioning> result; public List
> combinationSum2(int[] candidates, int target) { result = new ArrayList<>(); Arrays.sort(candidates); helper(candidates,new ArrayList<>(),0,target); return result; } private void helper(int[] candidates, List
temp,int start ,int remain){ if(remain == 0){ result.add(new ArrayList<>(temp)); return; } //加入remain判斷條件,跳過不必要的循環。 for(int i = start; i < candidates.length && remain >= candidates[i];i++){ if(i > start && candidates[i] == candidates[i-1]) continue; int tempRemain = remain - candidates[i]; if(tempRemain == 0 || tempRemain >= candidates[i]){ temp.add(candidates[i]); helper(candidates,temp,i+1,tempRemain); temp.remove(temp.size()-1); } } } } 給定一個回文字符串,要求將其分成多個子字符串,使得每個子字符串都是回文字符串,列出所有劃分可能。
public class Solution { List> result; public List
> partition(String s) { result = new ArrayList<>(); helper(new ArrayList<>(),s,0); return result; } private void helper(List
temp, String s, int start){ if(start == s.length()){ result.add(new ArrayList<>(temp)); return; } for(int i = start; i < s.length();i++){ if(isPanlidrome(s,start,i)){ temp.add(s.substring(start,i+1)); helper(temp,s,i+1); temp.remove(temp.size()-1); } } } private boolean isPanlidrome(String s, int low ,int high){ while(low < high) if(s.charAt(low++) != s.charAt(high--)) return false; return true; } } 如有錯誤,歡迎指出。
ref: general approach for ... problem
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/66095.html
摘要:感悟將遞歸當作一種類似的控制結構,通過迭代求解問題,遞歸通過分治求解問題。遞歸解決問題的環節是明確簡單情形明確相同形式的子問題。楊輝三角代碼分析簡單情形,可以理解為遞歸的終止條件,簡單情形里將不遞歸調用或者理解為無法用遞歸解決的情形。 感悟 將遞歸當作一種類似for/while的控制結構,for/while 通過迭代求解問題,遞歸通過分治求解問題。遞歸是這樣解決問題的。首先,這個問題存...
摘要:分布式的管理和當我在談論架構時我在談啥狀態碼詳解無狀態協議和請求支持哪些方法分層協議棧有哪些數據結構運用場景說說你常用的命令為什么要有包裝類面向對象的特征是啥是啥有什么好處系統設計工程在線診斷系統設計與實現索引背后的數據結構及算法原理軟技能 HTTP 【HTTP】分布式session的管理 【HTTP】Cookie和Session 【HTTP】當我在談論RestFul架構時我在談啥?...
摘要:先去空白,去掉空白之后取第一個字符,判斷正負符號,若是英文直接返回,若數字則不取?;匚臄殿}目描述判斷一個整數是否是回文數?;匚臄凳侵刚驈淖笙蛴液偷剐驈挠蚁蜃笞x都是一樣的整數。 JS算法題之leetcode(1~10) 前言 一直以來,前端開發的知識儲備在數據結構以及算法層面是有所暫缺的,可能歸根于我們的前端開發的業務性質,但是我認為任何的編程崗位都離不開數據結構以及算法。因此,我作為...
摘要:有效三角形的個數雙指針最暴力的方法應該是三重循環枚舉三個數字??偨Y本題和三數之和很像,都是三個數加和為某一個值。所以我們可以使用歸并排序來解決這個問題。注意因為歸并排序需要遞歸,所以空間復雜度為 ...
閱讀 2001·2021-11-24 10:45
閱讀 1857·2021-10-09 09:43
閱讀 1296·2021-09-22 15:38
閱讀 1227·2021-08-18 10:19
閱讀 2840·2019-08-30 15:55
閱讀 3065·2019-08-30 12:45
閱讀 2967·2019-08-30 11:25
閱讀 361·2019-08-29 11:30