17. 电话号码的字母组合

自己的答案:
自己写的时候,多次用到了String的拼接,很耗时间,对StringBuffer不熟悉,并且对回溯也不太熟悉
class Solution {public List<String> letterCombinations(String digits) {List<String> list = new ArrayList();if(digits==null||digits.length()==0) {return list;}Map<Integer,char[]> map =new HashMap();map.put(2,new char[]{'a','b','c'});map.put(3,new char[]{'d','e','f'});map.put(4,new char[]{'g','h','i'});map.put(5,new char[]{'j','k','l'});map.put(6,new char[]{'m','n','o'});map.put(7,new char[]{'q','p','r','s'});map.put(8,new char[]{'t','u','v'});map.put(9,new char[]{'w','x','y','z'});char[] ch = map.get(digits.charAt(0)-'0');for(int i = 0; i < ch.length;i++) {list.add(new String(ch[i]+""));}for(int i = 1 ; i < digits.length();i++) {ch = map.get(digits.charAt(i)-'0');List<String> listTemp = new ArrayList();for(int j = 0; j < list.size();j++){String s = list.get(j);for(int k = 0; k < ch.length;k++) {listTemp.add(s+ch[k]);}}list.clear();list.addAll(listTemp);}// list.stream().forEach(System.out::println);return list;}}
人家的代码:
我做的时候没有弄清楚buffer里的东西使用完以后该怎么删除. 没有掌握回溯的精髓
class Solution {public List<String> letterCombinations(String digits) {List<String> list = new ArrayList();if(digits==null||digits.length()==0) {return list;}Map<Integer,char[]> map =new HashMap();map.put(2,new char[]{'a','b','c'});map.put(3,new char[]{'d','e','f'});map.put(4,new char[]{'g','h','i'});map.put(5,new char[]{'j','k','l'});map.put(6,new char[]{'m','n','o'});map.put(7,new char[]{'q','p','r','s'});map.put(8,new char[]{'t','u','v'});map.put(9,new char[]{'w','x','y','z'});letter(list,digits,map,0,new StringBuffer());return list;}public void letter(List<String> list,String digits,Map<Integer,char[]> map ,int index,StringBuffer buffer) {if(digits.length()==index) {list.add(buffer.toString());return;}char[] ch = map.get(digits.charAt(index)-'0');for(int i = 0 ; i < ch.length;i++) {buffer.append(ch[i]);letter(list,digits,map,index+1,buffer); // 做的时候没有弄清楚buffer里的东西使用完以后该怎么删除. 没有掌握回溯的精髓buffer.deleteCharAt(index);}}}
22. 括号生成
数字 n 代表生成括号的对数,请你设计一个函数,用于能够生成所有可能的并且 有效的 括号组合。
 
自己写的:
代码写的很啰嗦,而且会有重复的,用了一个hashmap来判断
class Solution {List<String>[] resList = new ArrayList[9];public List<String> generateParenthesis(int n) {if(resList[n]!=null)return resList[n];List<String> list = new ArrayList();if(n==1){list.add("()");resList[1] =list;return list;}Set<String> set = new HashSet<>();List<String> L = generateParenthesis(n-1);for(String s:L) {String s1 = "("+s+")";list.add(s1);set.add(s1);}for(int i = 1 ; i < n;i++) {List<String> L1 = generateParenthesis(i);List<String> L2 = generateParenthesis(n-i);for(String s1:L1) {for(String s2:L2){String s = s1+s2;if(set.add(s))list.add(s1+s2);}}}resList[n] = list;return list;}}
回溯版本的答案
每次添加一个(或者一个)(的数目>)的数目才添加)
class Solution {List<String>[] resList = new ArrayList[9];public List<String> generateParenthesis(int n) {List<String> list = new ArrayList();generate(list,new StringBuffer(),0,0,0,n);return list;}public void generate(List<String> list,StringBuffer buffer,int open,int close,int index,int max) {if(index == max*2){list.add(buffer.toString());return;}if(open<max) {buffer.append('(');generate(list,buffer,open+1,close,index+1,max);buffer.deleteCharAt(index);}if(close<open) {buffer.append(')');generate(list,buffer,open,close+1,index+1,max);buffer.deleteCharAt(index);}}}
答案版本的自己写的
class Solution {ArrayList[] cache = new ArrayList[100];public List<String> generate(int n) {if (cache[n] != null) {return cache[n];}ArrayList<String> ans = new ArrayList<String>();if (n == 0) {ans.add("");} else {for (int c = 0; c < n; ++c) {for (String left: generate(c)) {for (String right: generate(n - 1 - c)) {ans.add("(" + left + ")" + right);}}}}cache[n] = ans;return ans;}public List<String> generateParenthesis(int n) {return generate(n);}}作者:LeetCode-Solution链接:https://leetcode-cn.com/problems/generate-parentheses/solution/gua-hao-sheng-cheng-by-leetcode-solution/来源:力扣(LeetCode)著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
47. 全排列 II
很好的题目!
对于[1,1,1,1,2,3,4,4,5]来说,要保证重复的数字的放置顺序是有序的。
class Solution {int n = 0;List<List<Integer>> result = new ArrayList();List<Integer> list = new ArrayList();boolean[] flag = null;public List<List<Integer>> permuteUnique(int[] nums) {n = nums.length;if(n==0){return result;}flag = new boolean[n];Arrays.sort(nums);dfs(nums,0);return result;}public void dfs(int[] nums,int idx) {if(idx==n){result.add(new ArrayList(list));return;}for(int i = 0; i < n;i++) {// 这个命令就是规定使重复的元素相对有序if(flag[i] || i >= 1 && nums[i] == nums[i-1] && !flag[i-1])continue;flag[i] = !flag[i];list.add(nums[i]);dfs(nums,idx+1);list.remove(idx);flag[i] = !flag[i];}}}
子集
78. 子集

回溯 ```java class Solution { int length = 0; List
- > result = new ArrayList();
 boolean[] flag = null;
 List
 
list = new ArrayList(); public List
- > subsets(int[] nums) {
 
length = nums.length;result.add(new ArrayList());if(length==0)return result;for(int i = 1; i <= length;i++) {dfs(nums,i,0,0); // 每次选择i长度的元素}return result;
}
void dfs(int[] nums,int size,int numSize,int start) {
if(size==numSize) {result.add(new ArrayList(list));return;}for(int i = start ; i < length;i++) {list.add(nums[i]);dfs(nums,size,numSize+1,i+1);list.remove(numSize);}
}
}
2. 位运算```javaclass Solution {public List<List<Integer>> subsets(int[] nums) {int length = nums.length;int num = (1<<length)-1;List<List<Integer>> result = new ArrayList();result.add(new ArrayList());List<Integer> list = new ArrayList();for(int i = 1; i <= num;i++) {int j = i;int len = 0;while(len<length) {if((j&(1<<len))!=0) {list.add(nums[len]);}len++;}result.add(new ArrayList(list));list.clear();}return result;}}
90. 子集 II

对于1,2,2,3,4,4,4:
1:0个1,一个1两种情况
2:0个、1个、2个 三种情况
3:0、1 两种
4:0、1、2、3 四种
共有:232*4=48
class Solution {List<List<Integer>> result = new ArrayList();List<Integer> list = new ArrayList();int n =0;public List<List<Integer>> subsetsWithDup(int[] nums) {n = nums.length;Arrays.sort(nums);dfs(nums,0);return result;}void dfs(int[] nums,int idx) {if(idx==n){result.add(new ArrayList(list));return;}int k =0; //重复元素的个数while(idx+k<n && nums[idx+k]==nums[idx]) k++;for(int i = 0 ; i <= k;i++) {// ==k的目的是为了使当前元素的最后一个重复元素可以在最后一步加入res中dfs(nums,idx+k);list.add(nums[idx]);}for(int i = 0 ; i <= k;i++) {list.remove(list.size()-1);}}}
473. 火柴拼正方形
剪枝的题目
https://www.acwing.com/solution/content/3785/

class Solution {int length;int has = 0;long size=0;boolean[] flag;List<Integer> nums;public boolean makesquare(int[] s) {length = s.length;long all = 0;for(int n:s) {all+=n;}if(length==0||all%4!=0)return false;size = all/4;flag = new boolean[length];nums = Arrays.stream(s).boxed().collect(Collectors.toList());Collections.sort(nums,Collections.reverseOrder());return dfs(0,0);}boolean dfs(int u,int cur) {if(cur == size) {u++;cur=0;}if(u==4) // u==4一定已经完成了,而且已经到达了最末尾,因为nums的总和=4*size{return true;}for(int i = 0 ;i < length;i++) {if(!flag[i] && cur+nums.get(i)<=size) {flag[i] = true;if(dfs(u,cur+nums.get(i))) {return true;}flag[i] = false;if(i==0) return false;while(i+1<length && nums.get(i+1)==nums.get(i)) i++;}}return false;}}
