摘要:通用算法思路總結(jié)初始結(jié)果列表??赡芤獙?shù)集排序,方便處理重復元素的情況。書寫遞歸函數(shù),先要考慮原點狀況,一般就是考慮什么情況下要將當前結(jié)果添加到結(jié)果列表中。每當一個元素添加到當前結(jié)果中之后,要再調(diào)用遞歸函數(shù),相當于固定了前綴窮舉后面的變化。
通用算法思路總結(jié):
初始結(jié)果列表。
可能要將數(shù)集排序,方便處理重復元素的情況。
調(diào)用遞歸函數(shù)。
書寫遞歸函數(shù),先要考慮原點狀況,一般就是考慮什么情況下要將當前結(jié)果添加到結(jié)果列表中。
for循環(huán)遍歷給定集合所有元素,不同題目區(qū)別在于進行循環(huán)的條件,具體看例子。每當一個元素添加到當前結(jié)果中之后,要再調(diào)用遞歸函數(shù),相當于固定了前綴窮舉后面的變化。
調(diào)用完之后要將當前結(jié)果中最后一個元素去掉,進行下一個循環(huán)才不會重復。
如果對于遞歸過程不熟悉的,可以用debug模式觀察參數(shù)在遞歸過程中的變化。
舉例包含:
78.Subsets
90.SubsetsII
46.Permuation
77.Combinations
39.Combination Sum
40.Combination Sum II
131.Panlindrome Partitioning
78.Subsets給一個數(shù)集(無重復數(shù)字),要求列出所有子集。
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); } } }
給一個數(shù)集(有重復數(shù)字),要求列出所有子集。
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); } }
給一個數(shù)集(無重復元素),返回所有排列。
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 給一個正整數(shù)n,要求返回1-n中k(k<=n)個數(shù)所有組合的可能。
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); } } } } 給一個數(shù)集和一個數(shù)字target,要求返回 用數(shù)集中數(shù)字加和等于target的所有組合 (數(shù)集中的數(shù)可以重復使用)。
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); } } } } 給一個數(shù)集和一個數(shù)字target,要求返回 用數(shù)集中數(shù)字加和等于target的所有組合 (數(shù)集中的數(shù)不可以重復使用)。
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判斷條件,跳過不必要的循環(huán)。 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
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/66095.html
摘要:感悟?qū)⑦f歸當作一種類似的控制結(jié)構(gòu),通過迭代求解問題,遞歸通過分治求解問題。遞歸解決問題的環(huán)節(jié)是明確簡單情形明確相同形式的子問題。楊輝三角代碼分析簡單情形,可以理解為遞歸的終止條件,簡單情形里將不遞歸調(diào)用或者理解為無法用遞歸解決的情形。 感悟 將遞歸當作一種類似for/while的控制結(jié)構(gòu),for/while 通過迭代求解問題,遞歸通過分治求解問題。遞歸是這樣解決問題的。首先,這個問題存...
摘要:分布式的管理和當我在談論架構(gòu)時我在談啥狀態(tài)碼詳解無狀態(tài)協(xié)議和請求支持哪些方法分層協(xié)議棧有哪些數(shù)據(jù)結(jié)構(gòu)運用場景說說你常用的命令為什么要有包裝類面向?qū)ο蟮奶卣魇巧妒巧队惺裁春锰幭到y(tǒng)設計工程在線診斷系統(tǒng)設計與實現(xiàn)索引背后的數(shù)據(jù)結(jié)構(gòu)及算法原理軟技能 HTTP 【HTTP】分布式session的管理 【HTTP】Cookie和Session 【HTTP】當我在談論RestFul架構(gòu)時我在談啥?...
摘要:先去空白,去掉空白之后取第一個字符,判斷正負符號,若是英文直接返回,若數(shù)字則不取?;匚臄?shù)題目描述判斷一個整數(shù)是否是回文數(shù)?;匚臄?shù)是指正序從左向右和倒序從右向左讀都是一樣的整數(shù)。 JS算法題之leetcode(1~10) 前言 一直以來,前端開發(fā)的知識儲備在數(shù)據(jù)結(jié)構(gòu)以及算法層面是有所暫缺的,可能歸根于我們的前端開發(fā)的業(yè)務性質(zhì),但是我認為任何的編程崗位都離不開數(shù)據(jù)結(jié)構(gòu)以及算法。因此,我作為...
摘要:有效三角形的個數(shù)雙指針最暴力的方法應該是三重循環(huán)枚舉三個數(shù)字??偨Y(jié)本題和三數(shù)之和很像,都是三個數(shù)加和為某一個值。所以我們可以使用歸并排序來解決這個問題。注意因為歸并排序需要遞歸,所以空間復雜度為 ...
閱讀 2028·2021-11-24 10:45
閱讀 1882·2021-10-09 09:43
閱讀 1330·2021-09-22 15:38
閱讀 1254·2021-08-18 10:19
閱讀 2861·2019-08-30 15:55
閱讀 3089·2019-08-30 12:45
閱讀 2993·2019-08-30 11:25
閱讀 390·2019-08-29 11:30